NeV*_*ada 10 c++ templates operator-overloading
我正在尝试编写函数定义来重载类定义之外的运算符">>"和"<<",尽管在同一个文件中,如您所见.我收到以下错误:
1>Source.obj : error LNK2019: unresolved external symbol "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class MyClass<int> &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$MyClass@H@@@Z) referenced in function _main
1>Source.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class MyClass<int>)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@V?$MyClass@H@@@Z) referenced in function _main
1>Source.obj : error LNK2019: unresolved external symbol "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class MyClass<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$MyClass@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@@Z) referenced in function _main
1>Source.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class MyClass<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@V?$MyClass@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@@Z) referenced in function _main
Run Code Online (Sandbox Code Playgroud)
我一直在这条河上下河.奇怪的是,如果我在类定义中编写它们的定义,它可以完美地工作.
#include <iostream>
#include <string>
using namespace std;
template <class MYTYPE>
class MyClass {
MYTYPE *myVector;
int dim;
string name;
public:
MyClass(int, string);
MyClass() {};
friend istream& operator>>(istream&, MyClass<MYTYPE>&);
friend ostream& operator<<(ostream&, MyClass<MYTYPE>);
};
template <class MYTYPE>
MyClass<MYTYPE>::MyClass(int x, string y) {
dim = x;
name = y;
myVector = new MYTYPE[dim];
}
template <class MYTYPE>
istream& operator>>(istream& X, MyClass<MYTYPE>& a){
cout<<"Reading vector: "<<a.name<<endl;
for(int indice = 0; indice < a.dim; indice++){
cout<<a.name<<'['<<indice<<"]= ";
X >> a.myVector[indice];
}
return X;
}
template <class MYTYPE>
ostream& operator<<(ostream& X, MyClass<MYTYPE> a){
X<<"Vector: "<<a.name<<endl;
for(int indice = 0; indice < a.dim; indice++)
X<<a.myVector[indice]<<' ';
X<<endl;
return X;
}
int main() {
MyClass<int> object(4, "Ints vector");
MyClass<string> object2(5, "String vector");
cin >> object;
cin >> object2;
cout << object;
cout << object2;
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在您的代码中,友元操作符的声明MyClass应如下所示:
template<typename T> friend istream& operator>>(istream&, MyClass<T>&);
template<typename T> friend ostream& operator<<(ostream&, MyClass<T>);
Run Code Online (Sandbox Code Playgroud)
也就是说,它们应该有自己的模板参数.
一个有效的定义MyClass基于问题提供一个如下:
template <class MYTYPE>
class MyClass {
MYTYPE *myVector;
int dim;
string name;
public:
MyClass(int, string);
MyClass() {}
template<typename T>
friend istream& operator>>(istream&, MyClass<T>&);
template<typename T>
friend ostream& operator<<(ostream&, MyClass<T>);
};
Run Code Online (Sandbox Code Playgroud)
调高编译器的警告级别会有所帮助.通过使用-Wallwith g++,我在链接器错误之前收到以下警告.
socc.cc:13:58: warning: friend declaration ‘std::istream& operator>>(std::istream&, MyClass<MYTYPE>& )’ declares a non-template function [-Wnon-template-friend]
friend istream& operator>>(istream&, MyClass<MYTYPE>&);
^
socc.cc:13:58: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
socc.cc:14:57: warning: friend declaration ‘std::ostream& operator<<(std::ostream&, MyClass<MYTYPE> ’ declares a non-template function [-Wnon-template-friend]
friend ostream& operator<<(ostream&, MyClass<MYTYPE>);
Run Code Online (Sandbox Code Playgroud)
您需要为函数operator>>和operator<<函数使用函数模板.您可以在类的定义之前声明它们:
// Forward the class template.
template <class MYTYPE> class MyClass;
// Declare the function templates.
template <class MYTYPE>
std::istream& operator>>(std::istream&, MyClass<MYTYPE>&);
template <class MYTYPE>
std::ostream& operator<<(st::ostream&, MyClass<MYTYPE>);
Run Code Online (Sandbox Code Playgroud)
然后,您将必须使用friend具有适当模板参数的声明.
// This makes sure that operator>><int> is not a friend of MyClass<double>
// Only operator>><double> is a friend of MyClass<double>
friend std::istream& operator>><MYTYPE>(std::istream&, MyClass<MYTYPE>&);
friend std::ostream& operator<<<MYTYPE>(std::ostream&, MyClass<MYTYPE>);
Run Code Online (Sandbox Code Playgroud)
这是为我构建的代码的更新版本.我没有尝试过运行它.
#include <iostream>
#include <string>
using namespace std;
template <class MYTYPE> class MyClass;
template <class MYTYPE>
std::istream& operator>>(std::istream&, MyClass<MYTYPE>&);
template <class MYTYPE>
std::ostream& operator<<(std::ostream&, MyClass<MYTYPE>);
template <class MYTYPE>
class MyClass {
MYTYPE *myVector;
int dim;
string name;
public:
MyClass(int, string);
MyClass() {};
friend std::istream& operator>><MYTYPE>(std::istream&, MyClass<MYTYPE>&);
friend std::ostream& operator<<<MYTYPE>(std::ostream&, MyClass<MYTYPE>);
};
template <class MYTYPE>
MyClass<MYTYPE>::MyClass(int x, string y) {
dim = x;
name = y;
myVector = new MYTYPE[dim];
}
template <class MYTYPE>
std::istream& operator>>(std::istream& X, MyClass<MYTYPE>& a){
cout<<"Reading vector: "<<a.name<<endl;
for(int indice = 0; indice < a.dim; indice++){
cout<<a.name<<'['<<indice<<"]= ";
X >> a.myVector[indice];
}
return X;
}
template <class MYTYPE>
std::ostream& operator<<(std::ostream& X, MyClass<MYTYPE> a){
X<<"Vector: "<<a.name<<endl;
for(int indice = 0; indice < a.dim; indice++)
X<<a.myVector[indice]<<' ';
X<<endl;
return X;
}
int main() {
MyClass<int> object(4, "Ints vector");
MyClass<string> object2(5, "String vector");
cin >> object;
cin >> object2;
cout << object;
cout << object2;
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)