带有 Armadillo 的 C++ 函数模板
Function templates in C++ with Armadillo
我正在使用犰狳线性代数库编写一些函数模板,但遇到了一些错误。我仍在学习 C++ 及其方面,因此非常感谢任何可能的解决方案。我的大部分功能如下所示,
template<typename T1>
void some_function(const Mat<T1> & p)
{
unsigned int n = p.n_rows;
// do some stuffs...
// ....
}
我的主要功能包括:
Mat<double> A = ones<Mat<double>>(4,4);
int a(2);
some_function(A); // runs perfectly
some_function(a*A); // compilation error as follows
test_function.hpp:35:8: note: template argument deduction/substitution failed:
test.cpp:22:17: note: ‘arma::enable_if2<true, const arma::eOp<arma::Mat<double>, arma::eop_scalar_times> >::result {aka const arma::eOp<arma::Mat<double>, arma::eop_scalar_times>}’ is not derived from ‘const arma::Mat<eT>’
some_function(a*A);
如果我改变函数如下:
template<typename T1>
void some_function(const T1 & p)
{
unsigned int n = p.n_rows;
// do some stuffs...
// ....
}
然后给出编译错误如下:
test_function.hpp: In instantiation of ‘bool some_function(const T1&) [with T1 = arma::eOp<arma::Mat<double>, arma::eop_scalar_times>]’:
test.cpp:22:17: required from here
test_function.hpp:37:26: error: ‘const class arma::eOp<arma::Mat<double>, arma::eop_scalar_times>’ has no member named ‘n_rows’
unsigned int n = p.n_rows;
但是非模板函数可以完美运行,比如
void some_function(const Mat<double> & p)
{
unsigned int n = p.n_rows();
// do some stuffs...
// ....
}
有什么解决办法吗??
我认为有了这些帮手:
template <typename T>
const Mat<T>& as_Mat(const Mat<T>& m) {return m;}
template<typename T1, typename eop_type>
Mat<typename T1::elem_type> as_Mat(const eOp<T1, eop_type>& X)
{
return {X};
}
你可以写:
template<typename T>
void some_function(const T & p)
{
const auto& mat = as_mat(p);
unsigned int n = mat.n_rows();
// do some stuffs...
// ....
}
使用.eval()成员函数强制将Armadillo表达式转换为矩阵。
然后您可以使用 .eval()
的结果作为函数的输入。例如:
mat A(10,20,fill::randu);
mat B(10,20,fill::randu);
some_function( (A+B).eval() );
另请注意,Mat class 没有名为 n_rows() 的成员函数。相反,它有一个名为 n_rows 的只读变量。例如:
unsigned int n = X.n_rows;
在Jarod42的post之后,我花了一些时间在这件事上,并找到了解决这个问题的另一种可能的方法,非常类似于 Jarod42的一个。我正在回复它作为任何可能像我一样陷入同样问题的人的答案。
我只是更改了 Jarod42 已经编写的第二个 as_Mat
函数。
template <typename T>
const Mat<T>& as_Mat(const Mat<T>& m) {return m;}
template<typename T>
Mat<typename T::elem_type> as_Mat(const T& X)
{
return {X};
}
并且所有用户定义的函数都将像以前一样包含一行。
template<typename T>
void some_function(const T & X)
{
const auto& Y = as_Mat(X);
// do some stuffs with Y...
// ....
}
这样任何延迟的评估都会被转换成矩阵,例如。 A+B
, A*B
, i*A
(i
= int, complex<>,double...) 等等等等等等
虽然我不确定代码的性能,而且正如 mtall 提到的 .eval()
函数一样,此修复对于构建模板化非常有帮助使用 Armadillo 的图书馆,图书馆用户不需要每隔一段时间输入 .eval()
。再次感谢大家的帮助和关注。
我正在使用犰狳线性代数库编写一些函数模板,但遇到了一些错误。我仍在学习 C++ 及其方面,因此非常感谢任何可能的解决方案。我的大部分功能如下所示,
template<typename T1>
void some_function(const Mat<T1> & p)
{
unsigned int n = p.n_rows;
// do some stuffs...
// ....
}
我的主要功能包括:
Mat<double> A = ones<Mat<double>>(4,4);
int a(2);
some_function(A); // runs perfectly
some_function(a*A); // compilation error as follows
test_function.hpp:35:8: note: template argument deduction/substitution failed:
test.cpp:22:17: note: ‘arma::enable_if2<true, const arma::eOp<arma::Mat<double>, arma::eop_scalar_times> >::result {aka const arma::eOp<arma::Mat<double>, arma::eop_scalar_times>}’ is not derived from ‘const arma::Mat<eT>’
some_function(a*A);
如果我改变函数如下:
template<typename T1>
void some_function(const T1 & p)
{
unsigned int n = p.n_rows;
// do some stuffs...
// ....
}
然后给出编译错误如下:
test_function.hpp: In instantiation of ‘bool some_function(const T1&) [with T1 = arma::eOp<arma::Mat<double>, arma::eop_scalar_times>]’:
test.cpp:22:17: required from here
test_function.hpp:37:26: error: ‘const class arma::eOp<arma::Mat<double>, arma::eop_scalar_times>’ has no member named ‘n_rows’
unsigned int n = p.n_rows;
但是非模板函数可以完美运行,比如
void some_function(const Mat<double> & p)
{
unsigned int n = p.n_rows();
// do some stuffs...
// ....
}
有什么解决办法吗??
我认为有了这些帮手:
template <typename T>
const Mat<T>& as_Mat(const Mat<T>& m) {return m;}
template<typename T1, typename eop_type>
Mat<typename T1::elem_type> as_Mat(const eOp<T1, eop_type>& X)
{
return {X};
}
你可以写:
template<typename T>
void some_function(const T & p)
{
const auto& mat = as_mat(p);
unsigned int n = mat.n_rows();
// do some stuffs...
// ....
}
使用.eval()成员函数强制将Armadillo表达式转换为矩阵。
然后您可以使用 .eval()
的结果作为函数的输入。例如:
mat A(10,20,fill::randu);
mat B(10,20,fill::randu);
some_function( (A+B).eval() );
另请注意,Mat class 没有名为 n_rows() 的成员函数。相反,它有一个名为 n_rows 的只读变量。例如:
unsigned int n = X.n_rows;
在Jarod42的post之后,我花了一些时间在这件事上,并找到了解决这个问题的另一种可能的方法,非常类似于 Jarod42的一个。我正在回复它作为任何可能像我一样陷入同样问题的人的答案。
我只是更改了 Jarod42 已经编写的第二个 as_Mat
函数。
template <typename T>
const Mat<T>& as_Mat(const Mat<T>& m) {return m;}
template<typename T>
Mat<typename T::elem_type> as_Mat(const T& X)
{
return {X};
}
并且所有用户定义的函数都将像以前一样包含一行。
template<typename T>
void some_function(const T & X)
{
const auto& Y = as_Mat(X);
// do some stuffs with Y...
// ....
}
这样任何延迟的评估都会被转换成矩阵,例如。 A+B
, A*B
, i*A
(i
= int, complex<>,double...) 等等等等等等
虽然我不确定代码的性能,而且正如 mtall 提到的 .eval()
函数一样,此修复对于构建模板化非常有帮助使用 Armadillo 的图书馆,图书馆用户不需要每隔一段时间输入 .eval()
。再次感谢大家的帮助和关注。