c++ - 哪个命名空间包含这个友元函数的声明?

标签 c++ c++11 namespaces lookup argument-dependent-lookup

下面的 friend 函数不是通过普通查找 (§7.3.1.2/3) 找到的,而是通过 ADL 找到的 (§3.4.2/4 第二个要点),因此代码编译通过并正常执行(live example)。但是函数 f 没有在任何命名空间中声明。例如,如果您尝试将调用 f(x); 替换为这些调用中的任何一个 ::f(x);A::f(x );A::X::f(x);,代码将无法编译。哪个命名空间包含这个友元函数的声明?标准对此有何规定?

#include <iostream>
namespace A {
    class X {
        int i;
        friend void f(X x) { std::cout << x.i << '\n'; }
    public:
        X():i(101){}
    };
}

int main()
{
    A::X x;
    f(x);
}

最佳答案

来自 C++ 标准

11.3 friend

6 A function can be defined in a friend declaration of a class if and only if the class is a non-local class (9.8), the function name is unqualified, and the function has namespace scope. [ Example:

class M { friend void f() { } // definition of global f, a friend of M,
                              // not the definition of a member function
};

—end example ]

Amd 其他引用(7.3.1 命名空间定义)

3 Every name first declared in a namespace is a member of that namespace. If a friend declaration in a non-local class first declares a class, function, class template or function template98 the friend is a member of the innermost enclosing namespace. The friend declaration does not by itself make the name visible to unqualified lookup (3.4.1) or qualified lookup (3.4.3). [ Note: The name of the friend will be visible in its namespace if a matching declaration is provided at namespace scope (either before or after the class definition granting friendship). —end note ] If a friend function or function template is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (3.4.2). If the name in a friend declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace. [ Note: The other forms of friend declarations cannot declare a new member of the innermost enclosing namespace and thus follow the usual lookup rules. —end note ]

我想提一下,将函数名括在括号中会抑制参数相关查找。

对于这段代码

int main()
{
    A::X x;
    ( f )(x);
}

将找不到函数 f。

关于c++ - 哪个命名空间包含这个友元函数的声明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25692402/

相关文章:

c++ - 用于模板函数特化的 Enable_if

c++ - 如何在 std::for_each 中使用 std::toupper?

c++ - 编写二进制文件模板函数

c# - 命名空间 '<global namespace>' 包含与别名 'PersianDate' 冲突的定义

c++ - func upper_bound 的参数?

c++ - 如何将浮点文字转换为相同位模式的无符号整数

XSLT - 使用复制命名空间时,未引用的命名空间仍会传播 ="no"

c++ - LLVM 编译器 2.0 : Warning with "using namespace std;"

c++ - 向打开的文件添加行?

c++ - 将可变参数函数参数转发到另一个可变参数函数而无需成本