在没有 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
我试图在 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