您可以实例化模板的非专用版本并在专用版本中继承它吗?
Can you instantiate the unspecialized version of a template and inherit from it inside the specialization?
我正在尝试将 Vector
定义为 row/column 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
的内容放入初始定义和所有特化中。但这远非惯用语。
这是一种方法:
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
的评估延迟到模板查找的第二阶段。
您可以使用SFINAE来禁用方法。有必要使模板方法的模板参数依赖于 class 模板参数。
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);
}
在 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。
我正在尝试将 Vector
定义为 row/column 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
的内容放入初始定义和所有特化中。但这远非惯用语。
这是一种方法:
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
的评估延迟到模板查找的第二阶段。
您可以使用SFINAE来禁用方法。有必要使模板方法的模板参数依赖于 class 模板参数。
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);
}
在 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。