繁体   English   中英

带Armadillo的C ++中的函数模板

[英]Function templates in C++ with Armadillo

我正在使用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...
    // ....
}

任何解决方案?

使用.eval()成员函数将Armadillo表达式强制转换为矩阵。

然后,您可以将.eval()的结果用作函数的输入。 例如:

mat A(10,20,fill::randu);
mat B(10,20,fill::randu);

some_function( (A+B).eval() );

另请注意,Mat类没有名为n_rows()的成员函数。 相反,它具有一个名为n_rows的只读变量。 例如:

unsigned int n = X.n_rows;

我认为有了这些助手:

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...
    // ....
}

Jarod42的帖子之后,我花了一些时间在此问题上,并找到了解决该问题的另一种方法,与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+BA*Bi*Ai = int,complex <>,double ...)等等等

尽管我不确定代码的性能,也不确定,正如mtall关于.eval()函数所提到的.eval() ,此修复对于使用Armadillo构建模板库非常有帮助,因为图书馆用户无需放置.eval()每隔一次。 再次感谢大家的帮助和关注。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM