根据模板启用类的成员

enable class's member depending on template

本文关键字:成员 启用      更新时间:2023-10-16

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

有什么方法可以实现我想要的吗?

将数据

成员保存在单独的类中,然后可以根据需要进行专用化。

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,因此它不会节省太多键入。

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