我想设计一个 m x n 矩阵类(作为由 m 行和 n 列参数化的模板)并且需要对其进行专门化,以便为其配备基于三个条件的数学上可能的操作:
- m > n
- m == n
- 没有针对 m < n 的专门化,即基本或默认实现
模板签名很简单:
template <size_t m, size_t n, typename T = double> class MatrixBase
{
....
};
我该怎么做?可以用类型特征来完成吗?或者我应该使用 std::conditional<>
或 std::enable_if<>
?。从概念上讲,我想要完成的是向类添加 方法,但不对其进行子类化和创建任何继承层次结构。我想将推导树用于其他用途,即矩阵内的数据存储。
所以我想要一个矩阵,如果声明为例如 MatrixBase<4, 4, float>
有(凭借特化)一个名为 inverse ()
的方法,而用 m <> n 声明的矩阵则不然。同样,用于 m > n 的矩阵的额外方法。
最佳答案
可以用std::enable_if
来完成:
template <size_t m, size_t n, typename T = double>
class MatrixBase
{
public:
template <typename T1 = T>
std::enable_if_t<m == n, MatrixBase<m, m, T1>> inverse() const
{
// Calculate inverse
return{};
}
};
int main(int argc, const char *argv[])
{
auto msquare = MatrixBase<4, 4>();
auto mrect = MatrixBase<4, 3>();
msquare.inverse(); // No error
mrect.inverse(); // Compilation error
return 0;
}
对于部分特化,您还可以使用 enable_if
:
template <size_t m, size_t n, typename T = double, typename E = void>
class MatrixBase
{
public:
template <typename T1 = T>
std::enable_if_t<m == n, MatrixBase<m, m, T1>> inverse() const
{
// Calculate inverse
return{};
}
};
template <size_t m, size_t n, typename T>
class MatrixBase<m, n, T, std::enable_if_t<m == n, void>>
{
public:
static bool m_equals_n()
{
return true;
}
};
template <size_t m, size_t n, typename T>
class MatrixBase<m, n, T, std::enable_if_t<n < m, void>>
{
public:
static bool m_greater_than_n()
{
return true;
}
};
template <size_t m, size_t n, typename T>
class MatrixBase < m, n, T, std::enable_if_t<m < n, void>>
{
public:
static bool m_less_than_n()
{
return true;
}
};
int main(int argc, const char *argv[])
{
auto msquare = MatrixBase<4, 4>();
auto m_4_3 = MatrixBase<4, 3>();
auto m_3_4 = MatrixBase<3, 4>();
msquare.m_equals_n();
//msquare.m_greater_than_n(); // Compilation error
m_4_3.m_greater_than_n();
m_3_4.m_less_than_n();
return 0;
}
关于c++ - 如何根据模板的两个整数参数之间的关系部分特化模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41645587/