C++ 编译期间未找到模板化函数
我有一个矩阵类,它支持使用运算符重载实现的标量值的操作。由于每个重载运算符函数除了所使用的运算符之外都具有相同的主体,因此我决定创建一个泛型函数,该函数将接受一个函数以及矩阵和标量值,以合并我的代码 下面是泛型函数,它是从重载加法运算符函数调用的:C++ 编译期间未找到模板化函数,c++,C++,我有一个矩阵类,它支持使用运算符重载实现的标量值的操作。由于每个重载运算符函数除了所使用的运算符之外都具有相同的主体,因此我决定创建一个泛型函数,该函数将接受一个函数以及矩阵和标量值,以合并我的代码 下面是泛型函数,它是从重载加法运算符函数调用的: // Generic function to take care of matrix operations template<typename T, typename F> Matrix<T> scal
// Generic function to take care of matrix operations
template<typename T, typename F>
Matrix<T> scalar_operation(const Matrix<T> &a, const T b, F f) {
std::vector<std::vector<T> > new_els = a.elements;
typename std::vector<std::vector<T> >::iterator it = new_els.begin();
typename std::vector<T>::iterator it_in;
for (; it != new_els.end(); ++it) {
it_in = it->begin();
for (; it_in != it->end(); ++it_in) {
*it_in = f(*it_in, b);
}
}
return Matrix<T>(new_els);
}
// Add scalar to all values in Matrix
template<typename T>
Matrix<T> operator+(const Matrix<T> &a, const T b) {
return scalar_operation(a, b, std::plus<T>());
}
//处理矩阵运算的通用函数
模板
矩阵标量运算(常数矩阵&a,常数tb,F){
std::vector new_els=a.元素;
typename std::vector::iterator it=new_els.begin();
typename std::vector::it_in的迭代器;
for(;it!=new_els.end();++it){
it_in=it->begin();
for(;it_in!=it->end();++it_in){
*it_in=f(*it_in,b);
}
}
回报矩阵(新的);
}
//将标量添加到矩阵中的所有值
模板
矩阵运算符+(常数矩阵和a,常数T b){
返回标量_操作(a,b,std::plus());
}
下面是matrix类中声明的函数:
template<class T>
class Matrix {
template<typename F>
friend Matrix<T> scalar_operation(const Matrix<T> &a, const T b, F f);
friend Matrix<T> operator+<>(const Matrix<T> &a, const T b);
friend Matrix<T> operator-<>(const Matrix<T> &a, const T b);
friend Matrix<T> operator*<>(const Matrix<T> &a, const T b);
friend Matrix<T> operator/<>(const Matrix<T> &a, const T b);
模板
类矩阵{
模板
友元矩阵标量运算(常数矩阵&a,常数tb,F);
友元矩阵算子+(常数矩阵&a,常数tb);
友元矩阵算子-(常数矩阵&a,常数tb);
友元矩阵算子*(常数矩阵&a,常数tb);
友元矩阵算子/(常数矩阵&a,常数tb);
当我分别实现重载运算符函数时,它们工作正常,但通过此实现,我得到以下编译器错误:
Undefined symbols for architecture x86_64:
"Matrix<float> scalar_operation<std::__1::plus<float> >(Matrix<float> const&, float, std::__1::plus<float>)", referenced from:
Matrix<float> operator+<float>(Matrix<float> const&, float) in matrix_test-3188cd.o
ld: symbol(s) not found for architecture x86_64
架构x86_64的未定义符号:
“矩阵标量运算(矩阵常数和,浮点,标准::uu 1::plus)”,引用自:
矩阵测试-3188cd.o中的矩阵运算符+(矩阵常数和浮点)
ld:找不到架构x86_64的符号
我想我的错误与矩阵标量\u操作(
行)有关,因为链接器似乎正在搜索具有此标头的函数,这与在我的文件中声明的方式略有不同,但我尝试修改我的声明,它会引发其他错误
为什么我会遇到这个错误?我如何修复它?谢谢
编辑:为了消除一些混淆,所有代码都在头文件中实现,因为它是一个模板类。没有相应的.cpp文件。代码有以下问题:类
矩阵
声明友元函数友元模板标量运算(…)
(是的,friend关键字不仅声明了私有访问,还声明了一个函数),但在外部作用域中没有这样的函数。只有模板标量_操作
,它不满足友元矩阵的声明。为什么?让我们尝试使用float
和std::plus
进行伪代码实例化(为简短起见,返回值和参数被省略):friend scalar\u操作(…)
和
标量运算(…)
正如我们所看到的,它们是不同的。因此在编译过程中,我们没有问题:我们在
操作符+
中有满足调用约定的正确的friend scalar\u操作声明。但是无法定义此类声明,我们在链接时遇到问题。解决方法是正确的friend声明:模板
友元矩阵标量运算(const Matrix&,const TT,F);
是否将模板函数实现放在.cpp文件中?您声明了友元模板友元矩阵标量运算(const Matrix&a,const T b,F);
但没有这样的函数,您只有模板矩阵标量运算(常数矩阵和a、常数T b、F)
@em2er那么,矩阵类主体之前的行模板
不起作用吗?因为对于重载的运算符函数,我不会在矩阵类主体内部用模板
声明它们,但它们仍然起作用模板友元标量操作
用一个模板参数声明友元函数,即您提供的e代码不包含此类函数,但它具有模板标量_操作
,这不适合您的好友声明。好友运算符+适合模板运算符+,因此没有问题。声明模板好友矩阵标量_操作(常量矩阵&a,常量T b,F F)
我认为这就是解决方案。@em2er谢谢!您的方法成功了,我只需要使用“T”以外的变量,这样编译器就不会将它与矩阵类主体之外的模板混为一谈了