我正在尝试执行矩阵求幂,但我不想复制/粘贴我的指数函数,而宁愿使用类模板。问题是对于增强矩阵,要乘以矩阵,可以使用prod
函数(而不是operator*
)。
似乎g ++无法找出我想要使用的模板。我用以下代码得到的错误是
41:37: error: no matching function for call to 'my_pow(boost::numeric::ublas::matrix<int>&, int, <unresolved overloaded function type>)'
这是代码:
#include <iostream>
using namespace std;
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
typedef long long int64;
template <class T, class M> T my_pow(T b, int64 e, M mult)
{
if (e == 1) return b;
if (e % 2 == 1) return mult(b, my_pow(b, e - 1, mult));
T tmp = my_pow(b, e / 2, mult);
return mult(tmp, tmp);
}
template <class T> T my_pow(T b, int64 e) { return my_pow(b, e, multiplies<T>()); }
int main()
{
using namespace boost::numeric::ublas;
matrix<int> m(3, 3);
for (unsigned i = 0; i < m.size1(); ++i)
for (unsigned j = 0; j < m.size2(); ++j)
m(i, j) = 3 * i + j;
std::cout << m << std::endl;
std::cout << my_pow(m, 2, prod) << std::endl;
}
有没有办法将prod()传递给my_pow,以便模板解析?感谢。
这种情况不清楚:b是基数,e是指数,my_pow是计算b ^ e
答案 0 :(得分:2)
您收到编译器错误的原因是prod
函数有很多重载,并且在调用my_pow
时,编译器需要知道要提供哪一个。{1}}。编译器无法推断您将pow函数应用于函数的第一个参数,因此在这里不知所措。
一种解决方案是将函数指针显式地转换为正确的类型,但是对于uBlas prod
重载,确定要转换的正确类型可能非常复杂。
另一种解决方案是创建一个多态函数对象,该对象委托给相应的pow函数。请注意,下面的实现假设prod( m, m)
返回与m相同类型的值(或可转换为它的值),但同样再次,这与您的my_pow
生成的假设相同。如果权力e
只能在运行时确定,那么这种创造的临时性很难避免。
可以解决这个问题的多态函数类的一个例子:
struct my_prod
{
template< typename M>
M operator()( const M &left, const M &right) const
{
return prod( left, right);
}
};
现在,如果您将对my_pow
的通话更改为:
std::cout << my_pow(m, 2, my_prod()) << std::endl;
它应该有效(对我而言)。
答案 1 :(得分:2)
有两个问题。首先,prod
是一个模板化函数,所以你不能只将prod
作为函数指针传递。相反,您需要传递prod<...>
并填写特定的模板参数。
但是在这种情况下仍然无法解决您的问题,因为即使使用指定的模板参数,prod
仍然有几个重载,编译器无法确定应该使用哪个。可以通过声明指定参数和返回类型的函数指针来解决此问题。但是,由于ublas
使用复杂的模板元编程,这将非常难看,我不推荐它。相反,我会在prod
周围编写一个包装函数来调用你想要的特定重载。这是一个非常通用的包装器,适用于任何ublas矩阵:
template <class E1, class E2>
typename boost::numeric::ublas::matrix_matrix_binary_traits<
typename E1::value_type, E1,
typename E2::value_type, E2>::result_type
my_prod(const boost::numeric::ublas::matrix_expression<E1>& e1,
const boost::numeric::ublas::matrix_expression<E1>& e2)
{
return prod(e1, e2);
}
然后,您可以使用my_pow
调用my_prod
,如下所示:
my_pow(m, 2, my_prod<matrix<int>, matrix<int> >)
只是为了好玩,这里是你需要传递的函数指针声明来解决模板参数和重载。这声明了一个名为prod_ptr
的函数指针,指向您想要的prod
的特定重载:
matrix_matrix_binary_traits<matrix<int>::value_type, matrix<int>, matrix<int>::value_type, matrix<int> >::result_type
(*prod_ptr)(const matrix_expression<matrix<int> >&, const matrix_expression<matrix<int> >&) =
&prod<matrix_matrix_binary_traits<matrix<int>::value_type, matrix<int>, matrix<int>::value_type, matrix<int> >::result_type, matrix<int>, matrix<int> >;
然后你可以使用函数指针调用my_pow
:
my_pow(m, 2, prod_ptr);