似乎确实有一些密切相关的问题,但我正在努力弄清楚如何应用他们的解决方案。
我有一个 traits 类,如下所示,用于操作我与 boost::numeric:ublas::matrix
一起使用的矩阵(以及其他矩阵实现)。我想只部分特化 switch_storage_order
,如评论中所示,但这失败了,因为函数不能部分特化。
我不想部分特化 matrix_traits
结构,因为这需要重新定义其所有成员的开销。一种解决方案是将每个与矩阵相关的函数分离到它自己的结构中,但最好将它们分组在一个特征类中。
有什么想法吗?也请随意评论特征概念的一般应用。
#include <boost/numeric/ublas/matrix.hpp>
enum matrix_storage_order {row_major, column_major};
template<class matrix_type>
struct matrix_traits {
// Default expects c-style row_major storage order.
static matrix_storage_order get_storage_order(const matrix_type& m)
{ return row_major; }
// By default can't change storage order so simply transpose.
static void switch_storage_order(matrix_type& m) { m.transpose(); }
};
namespace ublas = boost::numeric::ublas;
/* This doesn't work with error C2244:
* 'matrix_traits<matrix_type>::switch_storage_order' : unable to match function
* definition to an existing declaration
*/
// template<class value_type>
// void matrix_traits<ublas::matrix<value_type> >::switch_storage_order(
// ublas::matrix<value_type>& m) {
// m = boost::numeric::ublas::trans(m);
// }
typedef boost::numeric::ublas::matrix<double> matrix_double;
template<>
void matrix_traits<matrix_double>::switch_storage_order(matrix_double& m) {
m = boost::numeric::ublas::trans(m);
}
template <class matrix_type>
void function_requiring_column_major_storage_order(matrix_type& m) {
bool switch_order =
matrix_traits<matrix_type>::get_storage_order(m) == row_major;
if (switch_order) matrix_traits<matrix_type>::switch_storage_order(m);
// ... Do some work on m.
if (switch_order) matrix_traits<matrix_type>::switch_storage_order(m);
}
int main() {
matrix_double m;
// ... Fill the matrix.
function_requiring_column_major_storage_order(m);
}
最佳答案
如果您可以更改 static void switch_storage_order(matrix_type& m)
的实现,您可以使用如下内容:
// By default can't change storage order so simply transpose.
static void switch_storage_order(matrix_type& m) { transposer<matrix_type>()(m); }
与
// generic case
template <typename T>
struct transposer {
void opearator () (T& m) const { m.transpose(); }
};
// your specialization.
template<typename T>
struct transposer<ublas::matrix<T>> {
void opearator () (ublas::matrix<T>& m) const { m = boost::numeric::ublas::trans(m); }
};
关于c++ 模板类成员函数的部分特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24041127/