如何明确调用好友流运营商

How to explicitely call friend stream operator?

本文关键字:运营商 好友 调用 何明确      更新时间:2023-10-16

考虑到这个片段,正如预期的那样,gcc无法在NA::operator<lt;以及NB::运算符<lt;当调用流运算符而不指定命名空间时(通过调用类似于1的流运算符(。可以呼叫NB::operator<lt;明确地(如2(。这运行并具有预期的行为。但是,当尝试使用友元流运算符(如3(执行相同操作时,会引发构建错误,告诉该运算符<lt;不是NA的成员。为什么?NA::运算符<lt;似乎在情况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<lt?

这个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);

将由编译器解决。