考虑以下代码:
#include <stdio.h>
class A
{
public:
friend void foo(A a){ printf("3\n"); }
};
int main()
{
foo(A());
}
有用。但我认为这段代码是无效的。这是因为3.4.1/3:
为了确定(在解析期间)表达式是否是
函数调用的后缀表达式,常用的名称查找规则申请。
通常的名称查找规则无法找到友元函数,因为在我的情况下,友元声明的名称在全局命名空间中不可见。实际上是3.3.1/4:
好友声明(11.3)可能会引入一个(可能不可见的)名称
进入封闭的命名空间
这意味着该程序格式不正确。这是因为在判断的时候没有找到名字就是这个表达式foo(A());
是函数调用的后缀表达式。
我很困惑...
解析下面的程序时
#include <iostream>
using namespace std;
typedef int foo;
class A
{
public:
operator int(){
return 42;
}
};
int main()
{
cout << foo(A());
}
输出将是42
因为3.4.1/3
为了确定(在解析期间)表达式是否是
函数调用的后缀表达式,通常的名称查找规则
申请。
这意味着:确定是否foo
是后缀表达式(例如强制转换)或函数调用,编译器将首先使用名称查找并在全局命名空间和/或封闭范围/基类中搜索它(或使用完全限定的查找,如果可用)。
现在使用这段代码:
#include <iostream>
using namespace std;
class A
{
public:
friend int foo(A a){ return 55; }
operator int(){
return 42;
}
};
int main()
{
cout << foo(A());
}
上面会输出55
谢谢ADL http://en.wikipedia.org/wiki/Argument-dependent_name_lookup: foo 将通过在其潜在参数定义的范围内搜索来找到,即 A.
好友声明引入了您发布的名称(可能不可见)(3.3.1/4)
好友声明(11.3)可能会引入一个(可能不可见的)名称
进入封闭的命名空间
这意味着下面的代码将不起作用
#include <iostream>
using namespace std;
class A
{
public:
friend int foo(A a){ return 55; }
operator int(){
return 42;
}
};
int main()
{
cout << ::foo(A()); // Not found
cout << A::foo(A()); // Not found
}
您可能想要搜索“好友姓名注入“和/或巴顿-纳克曼技巧 http://en.wikipedia.org/wiki/Barton%E2%80%93Nackman_trick。
简短的故事:现在普通的查找无法找到好友声明。
因此,您发布的代码格式良好,因为 ADL 允许它按照我在前面的段落中解释的方式运行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)