在没有 SFINAE 的情况下将专用方法添加到 class 模板

Add specialized methods to a class template without SFINAE

我试图在 class 模板中定义一堆通用代码,然后添加一些特定于某些模板参数值的功能。简而言之:

// A vector of linear algebra
template <int n>
struct Vector
{
    // A bunch of functions not relying on a specific value for n
    float norm() { ... }
    float dot(const Vector& other) { ... }
private:
    float _data[n];
};

这一切都很好,但是 3D 向量特别具有 2 分量叉积,而其他维度的向量则没有(好吧,有些向量有,但这不是本文的重点)。我可以使用 SFINAE 来实现 cross 函数只为 n = 3 定义,但是我更希望能够定义所有不依赖于 n 的特定值的函数,然后实现其余的在独立的模板专业化中。

环顾四周时,我看到了从 class 模板继承的想法,但后来我不想重新声明新类型。此外,这显然不起作用(有点像预期的那样):

template <>
struct Vector<3> : public Vector<3> // error: invalid use of incomplete type ‘struct Vector<3>’
{
    Vector cross(const Vector& other) { ... }
};

换句话说,我想专门化我的 Vector class,但保留 class 模板中已经定义的所有函数,只添加更多。

有没有 SFINAE 的替代品,或者这是我唯一的选择?

如果满足条件,您可以使用通用模板别名来引入附加功能。

template <int n>
struct Vector_impl {
    // base implementation
}

struct Vector_3_impl : Vector_impl<3> {
    // n == 3 specific implementation
}

template <int n>
using Vector = std::conditional_t<n == 3, Vector_3_impl, Vector_impl<n>>;

不确定您到底想要什么...但在我看来您正在寻找一种自我继承,如下所示

// common part
template <int N, bool = N==3>
struct Vect
 {
   float foo_1 () { return 1.0f; }

   float _data[N];
 };

// additional methods for N==3 only
template <int N>
struct Vect<N, true> : public Vect<N, false>
 {
   float foo_2 () { return 2.0f; }

   // other additional methods
 };

你可以这样使用

   Vect<1>  v1;
   Vect<3>  v3;

   v1.foo_1();
   // v1.foo_2();  compilation error

   v3.foo_1();
   v3.foo_2();  // compile