我正在尝试定义一个 Vector
作为行列 Matrix
. Vector
需要一些方法 Matrix
没有的,所以我专门 Matrix
:
template<typename T, unsigned N, unsigned M>
struct Matrix {
T data[N][M];
};
template <typename T, unsigned N>
struct Matrix<T, N, 1> : public Matrix<T, N, 1> {
T at(unsigned index) {
return data[index][0];
}
};
template <typename T, unsigned N>
using Vector = Matrix<T, N, 1>;
这段代码不能编译,因为特殊化是一个递归类型。我在这里需要继承的原因是,我可以将所有的内容都包含在 Matrix
到专门化中,而不需要复制&粘贴。
有什么方法可以让我将原来的 Matrix
并从它那里继承?如果有的话,我的类型会不会变成非递归的?
我想到的另一个解决这个问题的方法是简单的 #include
楷体 Matrix
到初始定义和所有的特殊化。但这远远不是习惯性的。
你可以使用 SFINAE 来禁用方法。需要有模板方法,模板参数依赖于类模板参数。
C++11:
#include <type_traits>
template<typename T, unsigned N, unsigned M=1>
struct Matrix
{
T data[N][M];
template<typename V = T>
typename std::enable_if<M == 1, V>::type at(unsigned index)
{
return data[index][0];
}
};
template <typename T, unsigned N>
using Vector = Matrix<T, N, 1>;
int main()
{
Matrix<int, 2, 3> m;
Vector<int, 5> v;
// m.at(0);
v.at(1);
}
C++14:
#include <type_traits>
template<typename T, unsigned N, unsigned M=1>
struct Matrix
{
T data[N][M];
template<typename V = T>
std::enable_if_t<M == 1, V> at(unsigned index)
{
return data[index][0];
}
};
template <typename T, unsigned N>
using Vector = Matrix<T, N, 1>;
int main()
{
Matrix<int, 2, 3> m;
Vector<int, 5> v;
// m.at(0);
v.at(1);
}
C++20 (感谢Jarod42)。
template<typename T, unsigned N, unsigned M = 1>
struct Matrix
{
T data[N][M];
T at(unsigned index) requires (M == 1)
{
return data[index][0];
}
};
template <typename T, unsigned N>
using Vector = Matrix<T, N, 1>;
int main()
{
Matrix<int, 2, 3> m;
Vector<int, 5> v;
// m.at(0);
v.at(1);
}
下面是一种方法。
template<typename T, unsigned N, unsigned M>
struct Matrix {
T data[N][M];
};
template<typename T, unsigned N>
struct MatrixTN : Matrix <T, N, 1> {
T at(unsigned index) {
return this->data[index][0];
}
};
template<typename T, unsigned N>
using Vector = MatrixTN <T, N>;
注意: this->data
是需要延迟评估的。data
到第二阶段的模板查询。
在C++20中,你可以使用 requires
来丢弃方法。
template<typename T, unsigned N, unsigned M>
struct Matrix {
T data[N][M];
T at(unsigned index) requires (M == 1) {
return data[index][0];
}
};
在以前的标准中,你可能会用SFINAE代替。