问题描述
我正在尝试编写用于重载运算符>>"和<<"的函数定义在类定义之外,尽管在同一个文件中,如您所见.我收到以下错误:
I'm trying to write the function definition for overloading the operators ">>" and "<<" outside of the class definition, though in the same file, as you can see. I get the following errors:
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
我和这个人一起在河上游来游去.奇怪的是,如果我将它们的定义写在类定义中,它就可以完美运行.
I've been up and down the river with this one. The strange thing is that if I write their definitions inside the class definition, it works flawlessly.
#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;
}
推荐答案
调高编译器的警告级别有帮助.通过将 -Wall
与 g++
一起使用,我会在链接器错误之前收到以下警告.
Turning up the warning level of the compiler helps. By using -Wall
with g++
, I get the following warnings before the linker error.
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>);
您需要为 operator>>
和 operator<<
函数使用函数模板.您可以在类定义之前声明它们:
You need to use function templates for the operator>>
and operator<<
functions. You can declare them before the definition of the class with:
// 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>);
然后,您必须使用带有适当模板参数的 friend
声明.
Then, you'll have to use the friend
declaration with the appropriate template parameter.
// 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>);
这是为我构建的代码的更新版本.我还没试过运行它.
Here's an updated version of your code that builds for me. I haven't tried to run it.
#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;
}
这篇关于为 >> 实现重载并且<<模板类中的运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!