我正在处理我正在处理的作业的问题。我们正在编写一个复杂的数字类,它在它自己的命名空间中定义。我的一切都在工作,除了我的istream和ostream上的重载。让我发布一些代码:
namespace maths {
class complex_number{
public:
// lots of functions and two variables
friend std::istream& operator >>(std::istream &in, maths::complex_number &input);
}
}
std::istream& operator >>(std::istream &in, maths::complex_number &input)
{
std::cout << "Please enter the real part of the number > ";
in >> input.a;
std::cout << "Please enter the imaginary part of the number > ";
in >> input.b;
return in;
}
int main(int argc, char **argv)
{
maths::complex_number b;
std::cin >> b;
return 0;
}
我得到的错误如下:
com.cpp: In function ‘int main(int, char**)’:
com.cpp:159:16: error: ambiguous overload for ‘operator>>’ in ‘std::cin >> b’
com.cpp:159:16: note: candidates are:
com.cpp:131:15: note: std::istream& operator>>(std::istream&, maths::complex_number&)
com.cpp:37:26: note: std::istream& maths::operator>>(std::istream&, maths::complex_number&)
我花了一些时间在这里阅读论坛,偶然发现了一个关于名称隐藏的答案,但我似乎无法使用我的代码。非常感谢任何帮助!
答案 0 :(得分:3)
它不明确的原因是因为你有两个独立的功能。一个驻留在maths
命名空间中,并由类中标记为friend
的那个声明。这个可以通过Argument Dependent Lookup找到。您还可以在命名空间之外使用完整定义。这两者同样有效。
首先,它不访问该类的任何私有成员,因此不需要friend
声明。只是不要把它变成朋友,因为这只会伤害封装。
其次,我建议将定义移动到maths
命名空间,因为它与它所运行的类一起属于那里。如前所述,ADL仍然会找到它,因为第二个参数是该命名空间中的一个类型,因此搜索命名空间并找到重载。
总而言之,你应该最终得到这个:
namespace maths {
class complex_number{
public:
// lots of functions and two variables
};
std::istream& operator >>(std::istream &in, maths::complex_number &input)
{
std::cout << "Please enter the real part of the number > ";
in >> input.a;
std::cout << "Please enter the imaginary part of the number > ";
in >> input.b;
return in;
}
}
int main(int argc, char **argv)
{
maths::complex_number b;
std::cin >> b; //operator>> found by ADL
return 0;
}
最后一点是过载本身。输入真的不应该提示输入,它应该只读它们。这样,您就可以将它与键盘,文件或其他任何std::istream
衍生物一起使用。