声明一个 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>();
};