声明一个 constexpr 静态成员,它是模板参数中可能不存在的成员的函数?
Declare a constexpr static member that is a function of a potentially-absent member in a template parameter?
我有一个模板化的 class,我想为其提供一个 constexpr 整数,其值由模板参数中是否存在 constexpr 整数决定:
template<typename Traits>
class Foo
{
static constexpr int MaxDegree =
std::conditional<
std::is_integral<Traits::MaxDegree>::value,
std::integral_constant<int, Traits::MaxDegree>,
std::integral_constant<int, 0>
>::value;
};
struct TraitA { };
struct TraitB { constexpr static int MaxDegree = 1; };
int main()
{
std::cout
<< Foo<TraitA>::MaxDegree /* should be 0 */ << " "
<< Foo<TraitB>::MaxDegree; /* should be TraitB::MaxDegree == 1 */
<< "\n";
}
显然,这不起作用,因为 std::is_integral
对于 TraitA 失败。有什么有用的吗?
我只能使用 c++11。
Traits::MaxDegree
如果该成员不存在,则会产生编译器错误。这意味着您不能将此代码直接用作表达式的一部分。
你可以使用 SFINAE 的 constexpr 函数来实现这个:
template<class T>
constexpr typename std::enable_if<std::is_integral<decltype(T::MaxDegree)>::value, int>::type GetMaxDegree()
{
return T::MaxDegree;
}
template<class T>
constexpr int GetMaxDegree(...) // this one is only used, if the first version results in a substitution failure
{
return 0;
}
template<typename Traits>
class Foo
{
public:
static constexpr int MaxDegree = GetMaxDegree<Traits>();
};
我有一个模板化的 class,我想为其提供一个 constexpr 整数,其值由模板参数中是否存在 constexpr 整数决定:
template<typename Traits>
class Foo
{
static constexpr int MaxDegree =
std::conditional<
std::is_integral<Traits::MaxDegree>::value,
std::integral_constant<int, Traits::MaxDegree>,
std::integral_constant<int, 0>
>::value;
};
struct TraitA { };
struct TraitB { constexpr static int MaxDegree = 1; };
int main()
{
std::cout
<< Foo<TraitA>::MaxDegree /* should be 0 */ << " "
<< Foo<TraitB>::MaxDegree; /* should be TraitB::MaxDegree == 1 */
<< "\n";
}
显然,这不起作用,因为 std::is_integral
对于 TraitA 失败。有什么有用的吗?
我只能使用 c++11。
Traits::MaxDegree
如果该成员不存在,则会产生编译器错误。这意味着您不能将此代码直接用作表达式的一部分。
你可以使用 SFINAE 的 constexpr 函数来实现这个:
template<class T>
constexpr typename std::enable_if<std::is_integral<decltype(T::MaxDegree)>::value, int>::type GetMaxDegree()
{
return T::MaxDegree;
}
template<class T>
constexpr int GetMaxDegree(...) // this one is only used, if the first version results in a substitution failure
{
return 0;
}
template<typename Traits>
class Foo
{
public:
static constexpr int MaxDegree = GetMaxDegree<Traits>();
};