5 c++ templates operator-overloading operators visual-studio-2008
嘿,我收到链接器错误LNK2019:尝试使用重载+运算符时未解析的外部符号.我会告诉你从课堂上剪掉它,以及我是如何使用它的.如果你需要了解更多,请告诉我,我只是想让事情变得简洁.
/** vec.h **/
#ifndef __VEC_H_
#define __VEC_H_
#include <iostream>
#include <vector>
namespace xoor{
template<typename T>
class vec{
public:
inline friend vec<T> operator + (const vec<T>&, const vec<T>&);
inline const vec<T>& operator += (const vec<T>&);
private:
std::vector<T> m_index;
}; // Vec.
template<typename T>
vec<T>& operator + (const vec<T>& a, const vec<T>& b){
vec<T> product = a;
product += b;
return product;
} // Addition.
template<typename T>
const vec<T>& vec<T>::operator += (const vec<T>& v){
for (unsigned short i =0; i < m_index.size(); ++i){
if (i >= v.size())
break;
m_index[i] += v.getIndex()[i];
}
return * this;
} // Addition Compound.
} // xoor
#endif // __VEC_H_
Run Code Online (Sandbox Code Playgroud)
请注意,我也有[]重载,所以我只是用它来访问部分m_index.getIndex()只返回m_index.而size()返回m_index.size()
/** main.cpp **/
#include <iostream>
#include "vec.h"
void testHook();
int main(){
testHook();
system("PAUSE");
return 0;
}
void testHook(){
using namespace xoor;
vec<double> vA(3); // passing 3 for 3 elements
vec<double> vB(3);
// v + v
std::cout << "\n\tA + B = ";
vec<double> vAB(3);
vAB = vA + vB; // PRODUCES THE LNK2019
vAB.print(std::cout); // Outputs the vec class to the console.
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
Error 1 error LNK2019: unresolved external symbol "class xoor::vec<double> __cdecl xoor::operator+(class xoor::vec<double> const &,class xoor::vec<double> const &)" (??Hxoor@@YA?AV?$vec@N@0@ABV10@0@Z) referenced in function "void __cdecl testHook(void)" (?testHook@@YAXXZ) main.obj
Run Code Online (Sandbox Code Playgroud)
更新:
以下内容现在直接位于类定义之上.我继续得到相同的链接器错误,如上所述.
template<typename T>
class vec;
template<typename T>
vec<T> operator + (const vec<T>&, const vec<T>&);
Run Code Online (Sandbox Code Playgroud)
更新2:解决方案.
以上更新不正确.sbi的解决方案确实有效,我只是按照以下方式对运营商进行了模板化.
template<typename T>
vec<T> operator +<T> (const vec<T>&, const vec<T>&);
Run Code Online (Sandbox Code Playgroud)
sbi和大卫正在讨论为什么我首先使用朋友.最初我使用它们,因为你不能将两个参数传递给一个重载的二元运算符,比如+,并立即寻求朋友作为解决方案.事实证明,您仍然可以使用单个参数轻松使用二元运算符.这是最终的解决方案.
// ...
template<typename T>
class vec{
public:
const vec<T> operator + (const vec<T>&, const vec<T>&)const;
// ...
}; // Vec.
template<typename T>
const vec<T> vec<T>::operator + (const vec<T>& v)const{
matrix<T> product = *this;
vec(product += v);
} // Addition.
Run Code Online (Sandbox Code Playgroud)
此外,对于其他读这篇文章的人来说,在他的答案底部查看sbi的笔记是值得的.我一直在做的一些事情是多余的.
感谢大家的帮助.快乐的编码.
这里的返回类型:
inline friend vec<T> operator + (const vec<T>&, const vec<T>&);
Run Code Online (Sandbox Code Playgroud)
在这里不匹配:
template<typename T>
vec<T>& operator + (const vec<T>& a, const vec<T>& b){
vec<T> product = a;
product += b;
return product;
} // Addition.
Run Code Online (Sandbox Code Playgroud)
为了成为模板的朋友,我认为您需要在要与之建立联系的类定义之前声明该模板.但是,要编译此声明,您需要转发声明类模板.所以这应该工作:
template<typename T>
class vec;
template<typename T>
vec<T> operator + (vec<T>, const vec<T>&);
template<typename T>
class vec{
public:
friend vec<T> operator +<T> (vec<T>, const vec<T>&);
// ...
Run Code Online (Sandbox Code Playgroud)
这是operator+()功能模板的特定实例,即operator+<T>.(您还可以与模板的所有实例建立联系:
// no forward declarations necessary
template<typename T>
class some_class {
template<typename U>
friend void f(vec<U>&);
// ...
};
Run Code Online (Sandbox Code Playgroud)
然而,这比另一个更不常用.)
编辑:大卫注释让我思考(应该已经从一开始就做到了这一点!),而且导致这一发现的friend声明是不必要的.你operator+只使用()的一个public成员函数,因此不需要是类的一个.所以上面会简化到vecoperator+=friend
template<typename T>
class vec{
public:
// ...
};
template<typename T>
vec<T> operator + (vec<T> a, const vec<T>& b){
a += b;
return a;
}
Run Code Online (Sandbox Code Playgroud)
这里还有一些注意事项:
operator+()(你很好地在operator+=()BTW 之上实现)应该每个副本采用左参数.inline,因此定义它们.operator+=()返回非const引用,因为每个人都希望f(m1+=m2)即使工作f()需要它的参数作为非const参考.vec& operator += (const vec&);.(但是,您不能在模板外部执行此操作 - 例如,在类之外定义该运算符时.)std::vector的索引类型拼写std::vector<blah>::size_type,而不是 拼写unsigned short.