简体   繁体   English

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

[英]Function templates in C++ with Armadillo

I am writing some function templates using armadillo linear algebra library, but it encounters some errors. 我正在使用armadillo线性代数库编写一些功能模板,但是遇到一些错误。 I am still learning C++ and its aspects, so will be very much thankful for any possible solutions. 我仍在学习C ++及其方面,因此非常感谢任何可能的解决方案。 Most of my functions are like the following, 我的大部分功能如下

template<typename T1>
void some_function(const Mat<T1> & p)
{
    unsigned int n = p.n_rows;
    // do some stuffs...
    // ....
}

My main function contains: 我的主要功能包括:

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);

If I change the function as follows: 如果我按如下方式更改功能:

template<typename T1>
void some_function(const T1 & p)
{
    unsigned int n = p.n_rows;
    // do some stuffs...
    // ....
}

Then it gives the compilation error as follows: 然后给出如下编译错误:

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;

But the non-template functions work perfectly, like 但是非模板功能可以完美地工作,例如

void some_function(const Mat<double> & p)
{
    unsigned int n = p.n_rows();
    // do some stuffs...
    // ....
}

Any solutions?? 任何解决方案?

Use the .eval() member function to forcefully convert an Armadillo expression into a matrix. 使用.eval()成员函数将Armadillo表达式强制转换为矩阵。

You can then use the result of .eval() as the input to a function. 然后,您可以将.eval()的结果用作函数的输入。 For example: 例如:

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

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

Also note that the Mat class doesn't have a member function called n_rows(). 另请注意,Mat类没有名为n_rows()的成员函数。 Instead it has a read-only variable called n_rows . 相反,它具有一个名为n_rows的只读变量。 For example: 例如:

unsigned int n = X.n_rows;

I think that with those helpers: 我认为有了这些助手:

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};
}

You may write: 您可以写:

template<typename T>
void some_function(const T & p)
{
    const auto& mat = as_mat(p);
    unsigned int n = mat.n_rows();
    // do some stuffs...
    // ....
}

After Jarod42 's post, I put some time on this matter and found out another possible solution to this problem, very similar to Jarod42 's one. Jarod42的帖子之后,我花了一些时间在此问题上,并找到了解决该问题的另一种方法,与Jarod42的方法非常相似。 I am replying it as an answer for anyone who might stuck into this same problem like myself. 我将其作为对可能像我这样陷入同样问题的任何人的答复。 I just changed the second as_Mat function that Jarod42 has already written. 我只是更改了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};
}

And all user defined functions will contain one line as before. 和所有用户定义的函数一样,将包含一行。

template<typename T>
void some_function(const T & X)
{
    const auto& Y = as_Mat(X);
    // do some stuffs with Y...
    // ....
} 

This way any delayed evaluation will be converted into matrix, eg. 这样,任何延迟的评估都将转换为矩阵,例如。 A+B , A*B , i*A ( i = int, complex<>,double...) etc. etc. etc. A+BA*Bi*Ai = int,complex <>,double ...)等等等

Though I am not sure about the performance of the code and also, as mtall mentioned about .eval() function, this fix can be very much helpful to build templated libraries using Armadillo, where library users do not need to put .eval() every other time. 尽管我不确定代码的性能,也不确定,正如mtall关于.eval()函数所提到的.eval() ,此修复对于使用Armadillo构建模板库非常有帮助,因为图书馆用户无需放置.eval()每隔一次。 Again, thank you all for your kind help and attention. 再次感谢大家的帮助和关注。

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

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