我在自己的命名空间中定义了一个getline
函数:
namespace pru{
class A{
friend std::istream& getline(std::istream& in, A& a)
{
std::cout << "getline\n";
return in;
}
};
然后像往常一样在main中调用:
pru::A a;
pru::getline(std::cin, a);
但令人惊讶的是,它不能编译。g++和clang都给出了相同的错误:
'getline' is not a member of 'pru'
但是如果我调用不带pru
的getline
pru::A a;
getline(std::cin, a);
它编译了!为什么?getline是保诚的会员!
发布于 2019-05-12 16:46:44
这个answer应该可以解释所有的事情。我将仅为您的特定示例进行解释。在类中声明/定义的友元函数是封闭名称空间(在本例中为pru
)的一部分。但是它们在限定的查找中是不可见的,除非它们至少也在该名称空间中被声明。因为您没有显式地声明它,所以这段代码不会编译:
pru::A a;
pru::getline(std::cin, a);
你有没有这样做过:
namespace pru{
class A{
friend std::istream& getline(std::istream& in, A& a)
{
std::cout << "getline\n";
return in;
}
};
std::istream& getline(std::istream& in, A& a);//Can be placed anywhere in pru.
}
上面的方法也是可行的。正如答案所述,友元函数通过ADL是可见的。你可以阅读更多关于它的内容,例如here。这基本上意味着,因为参数来自std
和pru
名称空间,所以还会在它们中搜索getline
声明。
https://stackoverflow.com/questions/56101214
复制相似问题