考虑到此片段,按预期,gcc在调用流运算符而未指定名称空间时(通过调用像1那样的流运算符)找不到NA :: operator <<和NB :: operator <<之间的哪个符号。可以显式调用NB :: operator <<(如2)。运行并具有预期的行为。但是,当尝试与好友流运算符(如3)进行相同操作时,会产生一个构建错误,告诉运算符<<不是NA的成员。为什么? NA :: operator <<似乎在情况1)...
#include <iostream>
#include <vector>
#include <fstream>
namespace NA {
class A {
friend inline std::ostream & operator<<(std::ostream & s, const A & object) {
std::cout << "NA::operator<<" << std::endl;
return s;
}
};
}
namespace NB {
std::ostream & operator<<(std::ostream & s, const NA::A & object) {
std::cout << "NB::operator<<" << std::endl;
return s;
}
void func(const NA::A* a);
}
void NB::func(const NA::A* a) {
std::ofstream ofs;
//1)
//ofs << *a; //build error:
//error: ambiguous overload for 'operator<<' (operand types are 'std::ofstream' {aka 'std::basic_ofstream<char>'} and 'const NA::A')
//2)
//NB::operator<<(ofs, *a); //runs and displays NB::operator<<
//3)
NA::operator<<(ofs, *a); //build error:
//error: 'operator<<' is not a member of 'NA'
}
int main()
{
NA::A obj_a;
NB::func(&obj_a);
}
我的问题是,如何显式调用NA :: operator <<?
答案 0 :(得分:1)
这个cas有点奇怪。
对于此代码:
ofs << *a;
编译器清楚地指出两者之间存在歧义:
main.cpp:16:20: note: candidate: 'std::ostream& NB::operator<<(std::ostream&, const NA::A&)'
std::ostream & operator<<(std::ostream & s, const NA::A & object) {
^~~~~~~~
main.cpp:8:38: note: candidate: 'std::ostream& NA::operator<<(std::ostream&, const NA::A&)'
friend inline std::ostream & operator<<(std::ostream & s, const A & object) {
^~~~~~~~
但是当通过
显式调用运算符时NA::operator<<(ofs, *a);
编译器找不到它:
main.cpp:39:17: error: 'operator<<' is not a member of 'NA'
NA::operator<<(ofs, *a);
^~
我发现的唯一解决方法是在名称空间NA中声明一个函数,该函数将调用运算符,然后编译器可以选择一个好的函数:
namespace NA {
void print_it(std::ofstream & os, const A & a)
{
os << a;
}
}
好的,我感谢@Passer By的评论
在编译器中看不到函数的声明,而是添加如下方法的前向声明:
namespace NA {
class A;
std::ostream & operator<<(std::ostream & s, const A & object);
}
允许编译器查找声明,因此
NA::operator<<(ofs, *a);
将由编译器解决。