对依赖于参数的查找和友元函数定义的混淆

Confusion over argument dependent lookup and friend function definition

本文关键字:定义 函数 友元 依赖于 参数 查找      更新时间:2023-10-16

我有以下程序:

struct Foo {
    friend void foo (int) {}
    operator int () const { return 0; }
};
int main() {
    foo(Foo());  // This compiles fine
    foo(0);      // This fails to find `foo()`
    return 0;
}

我不知道标准的哪一部分定义了ADL规则,即对foo(0)的调用应该失败,而对foo(Foo())的调用应该成功。有人能照亮吗?

由于我自己的删除而重新打开,嗯?好吧,在juancapanza的提示下,我阅读了标准的相关部分,C++11§3.4.2,更加小心。我以前浏览得太快了。也就是说,第2段阐明:

对于函数调用中的每个参数类型T,都要考虑一组零个或多个关联命名空间和一组零或多个相关类。命名空间和类的集合完全由函数参数的类型(以及任何模板模板参数的命名空间)决定。用于指定类型的Typedef名称和使用声明对该集没有贡献。命名空间和类的集合是通过以下方式确定的:

  • 如果T是一个基本类型,那么它关联的名称空间和类集都是空的
  • 如果T是一个类类型(包括并集),那么它的关联类是:类本身;其所属类别(如有);及其直接和间接基类。其关联的命名空间是其关联类所属的命名空间。此外,如果T是类-模板专用化,则其相关联的命名空间和类还包括:与为模板类型参数提供的模板参数的类型相关联的名称空间和类(不包括模板-模板参数);任何模板模板参数都是其成员的命名空间;以及用作模板模板参数的任何成员模板都是其成员的类

第一个项目符号解释了传递int参数失败的原因。第二个项目符号解释了传入Foo实例的原因。

查看您的代码:

int main() {
    foo(Foo());  // This declares a global function "foo" taking a "Foo" as an argument
    foo(0);      // "foo" takes a "Foo" above, and theres no way to convert an int to a Foo...