是否可以按模板类型更改静态 const 类成员的值



我真的不知道这方面的术语,我只举一个例子:

template <typename T>
struct value_holder {
    T value;
    static const bool is_integer = ??; // if T is int or long set this to true, else set false
}

这样当我这样做时

value_holder<float> floaty;
std::cout << floaty.is_integer << "n";

它将打印 0

我必须如何定义成员is_integer以便它这样做?

您可以使用

std::is_same来执行此操作。
它遵循一个最小的工作示例:

#include<type_traits>
template <typename T>
struct value_holder {
    T value;
    static const bool is_integer = std::is_same<int, T>::value or std::is_same<long, T>::value;
};
int main() {
    static_assert(value_holder<int>::is_integer, "!");
    static_assert(not value_holder<char>::is_integer, "!");
}

另一种可能的方法是基于模板专用化。沿着这种方式应该可以工作:

template <typename T>
struct value_holder {
    T value;
    static const bool is_integer = false;
};
template <>
struct value_holder<int> {
    int value;
    static const bool is_integer = true;
};
template <>
struct value_holder<long> {
    long value;
    static const bool is_integer = true;
};

无论如何,从我的角度来看,它有点冗长,如果您的类包含多个数据成员,可能会很烦人。

正如昆汀的回答所说,你使用类型特征。 在您的示例中std::is_integral有意义:

template <typename T>
struct value_holder {
    T value;
    static constexpr bool is_integer = std::is_integral<T>::value;
};

不过,这与您的评论并不完全相符。 如果你真的希望is_integer只对intlong为真,那么你可以定义一个自定义类型特征:

template <typename T>
struct is_int_or_long : std::false_type {};
template <>
struct is_int_or_long<int> : std::true_type {};
template <>
struct is_int_or_long<long> : std::true_type {};
template <typename T>
struct value_holder {
    T value;
    static constexpr bool is_integer = is_int_or_long<T>::value;
};

当然,这可以通过使用std::is_same特征来缩短:

template <typename T>
struct value_holder {
    T value;
    static constexpr bool is_integer = std::is_same<T, int>::value || std::is_same<T, long>::value;
};

您正在寻找类型特征。 您可能会对std::is_integral感兴趣。

最新更新