根据模板启用类的成员

Amx*_*mxx 11 c++ member enable-if c++11

我已经知道你可以启用(或不启用)类的方法 std::enable_if

举个例子:

template<size_t D, size_t E>
class Field
{
  ...

  size_t offset(const std::array<float,D>& p) const
  {
    ...
  }

  template<typename TT = size_t>
  typename std::enable_if<D!=E, TT>::type
  offset(const std::array<float,E>& p) const
  {
    return offset(_projection(p));
  }

  ...
};
Run Code Online (Sandbox Code Playgroud)

这有助于无法调用在特定情况下无效的函数以及删除重载错误......对我而言,这非常好!

我想进一步让我的班级成员只在需要时出席.这样,如果我尝试使用一个原本不会被启动的异议,我会收到错误

我试着这样做

template<size_t D, size_t E>
class Field
{
  ...

  template<typename TT = projectionFunc>
  typename std::enable_if<D!=E, TT>::type _projection;
}
Run Code Online (Sandbox Code Playgroud)

但是编译器告诉我:

erreur: data member ‘_projection’ cannot be a member template
Run Code Online (Sandbox Code Playgroud)

有没有办法实现我想要的?

T.C*_*.C. 8

将数据成员保存在一个单独的类中,然后您可以根据需要进行专门化.

template<size_t D, size_t E>
class Field {
    template<size_t, size_t> struct Field_Members {
        int _projection;
    };
    template<size_t V> struct Field_Members<V, V> { };
    Field_Members<D, E> m;
};
Run Code Online (Sandbox Code Playgroud)

然后使用m._projection

Field_Members不必是嵌套的类模板; 如果需要,你可以把它移到外面.它也可以Field从它继承,但它然后它是一个依赖的基础,你必须写this->_projection,所以它不会节省太多的输入.


Wal*_*ter 7

AFAIK,在类模板中使用简单的SFINAE是不可能的.当然,您可以使成员的类型依赖于编译时条件,即通过std::conditional但不完全消除成员.

当然,你可以做的是使用另一个类模板,例如

template<bool Condition, typename T> struct Has { T value; };
template<typename T> struct Has<false,T> {};
Run Code Online (Sandbox Code Playgroud)

并声明此类型的成员(或基础)并通过Has<>::value以下方式访问该对象:

typename<Condition>
class foo
{
  Has<Condition, double> x;   // use x.value (only if Condition==true)
};
Run Code Online (Sandbox Code Playgroud)