c++ 根据模板启用类的成员

1l5u6lss  于 2023-07-01  发布在  其他
关注(0)|答案(2)|浏览(123)

我已经知道您可以使用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));
  }

  ...
};

这有助于不能够调用在特定情况下无效的函数,以及删除重载错误。对我来说,这很好
我想更进一步,只在需要的时候,让我们班的一些成员在场。这样的话,如果我尝试使用一个没有初始化的对象,我就会得到一个错误
我试着去做

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

  template<typename TT = projectionFunc>
  typename std::enable_if<D!=E, TT>::type _projection;
}

但是编译器告诉我:

erreur: data member ‘_projection’ cannot be a member template

有什么办法可以达到我的目的吗?

lkaoscv7

lkaoscv71#

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

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;
};

然后使用m._projection等。
Field_Members不必是嵌套类模板;如果需要的话,你可以把它移到外面去。也可以让Field继承它,但这样它就成了一个依赖基,你必须写this->_projection,所以它不会保存太多的输入。

siotufzp

siotufzp2#

AFAIK,这是不可能的类模板内的一个简单的SFINAE。当然,可以让成员的类型依赖于编译时条件,即:通过std::conditional,但不完全消除成员。
当然,您可以使用另一个类模板,如

template<bool Condition, typename T> struct Has { T value; };
template<typename T> struct Has<false,T> {};

并声明一个此类型的成员(或基),并通过Has<>::value访问该对象:

template<typename T, bool Condition>
class foo
{
  Has<Condition, T> x;   // use x.value (only if Condition==true)
};

相关问题