C ++名称查找-来自标准的示例 [英] C++ name lookup - example from the standard
问题描述
我需要从标准[basic.lookup.unqual]/3中对该示例进行解释:
I need an explanation on this example from standard [basic.lookup.unqual]/3:
typedef int f;
namespace N {
struct A {
friend void f(A &);
operator int();
void g(A a) {
int i = f(a); // f is the typedef, not the friend
// function: equivalent to int(a)
}
};
}
我认为void N::f(A &)
比int(a)
更近,因为它不涉及类型转换运算符.但是我不确定,因为该标准仅包含类型转换"的一个实例.
I would argue that void N::f(A &)
is closer than int(a)
because it does not involve the type-cast operator. I cannot however be sure because the standard contains only one instance of "type cast".
顺便说一句,在MSVC2015中编译该代码失败(但它可以在clang和g ++中工作).
By the way, compiling that code fails in MSVC2015 (but it works in clang and g++).
错误C2440'正在初始化':无法从'void'转换为'int'
Error C2440 'initializing': cannot convert from 'void' to 'int'
更新 解决一些评论.
UPDATE Addressing some of the comments.
-
类型转换在形式上被称为类型转换",在(12.3)中进行了介绍(感谢jefffrey).
Type casting is formally known as "type conversions" and they are covered in (12.3) (thanks jefffrey).
我正在寻找的是语法解析的描述.特别是为什么postfix-expression ( expression-list opt )
被simple-type-specifier ( expression-list opt )
践踏.由于根据(5.2),这两个表达式都是从左到右求值的.因此,在计算::N::A::g
中的表达式时,在(a)
之前的两个候选中,::N::f
应该比::f
更近.
What I am looking for is a description of the syntax parsing. In particular, why postfix-expression ( expression-list opt )
is trampled over by simple-type-specifier ( expression-list opt )
. Since according to (5.2), both of those expression are evaluated left-to-right. Hence, out of the two candidates to be before the (a)
, ::N::f
should be closer than ::f
when evaluating expressions in ::N::A::g
.
推荐答案
这里发生了一些事情.如包含示例的注释所述(3.4/3):
There are a few things going on here. As the note containing the example says (3.4/3):
出于确定(解析期间)表达式是否为函数调用的后缀表达式的目的,通常使用名称查找规则. 3.4.2中的规则对表达式的句法解释没有影响.
For purposes of determining (during parsing) whether an expression is a postfix-expression for a function call, the usual name lookup rules apply. The rules in 3.4.2 have no effect on the syntactic interpretation of an expression.
因此,首先我们需要使用 don'的名称查找规则来了解f
是简单类型说明符还是后缀表达式 t 包括3.4.2节.在这些规则下,功能N::f
不可见.
So first we need to know whether f
is a simple-type-specifier or a postfix-expression, using name lookup rules that don't include section 3.4.2. And under these rules, the function N::f
is not visible.
7.3.1.2/3:
7.3.1.2/3:
如果非本地类中的
friend
声明首先声明了一个类,函数,类模板或函数模板,则该朋友是最内部封闭的命名空间的成员.friend
声明本身不会使名称对不合格的查找(3.4.1)或合格的查找(3.4.3)可见.
If a
friend
declaration in a non-local class first declares a class, function, class template or function template the friend is a member of the innermost enclosing namespace. Thefriend
declaration does not by itself make the name visible to unqualified lookup (3.4.1) or qualified lookup (3.4.3).
因此,不合格的查找根本看不到任何N::f
声明,而仅找到::f
,它是类型名.因此语法是简单类型说明符 (
表达式列表 opt )
,而不是后缀表达式 em> (
表达式列表 opt )
,并且不依赖于参数的查找(3.4.2).
Therefore the unqualified lookup does not see any declaration of N::f
at all, and finds only ::f
, which is a typename. So the syntax is simple-type-specifier (
expression-list opt )
and not postfix-expression (
expression-list opt )
, and argument-dependent lookup (3.4.2) does not apply.
((如果不合格的查找找到了一个函数名,则3.4.2将适用,并且尽管没有声明,也可以将N::f
包括在候选列表中.如果N::f
以前有一个声明不是friend
声明,它将赢得不合格的查找.)
( If the unqualified lookup had found a function name, 3.4.2 would apply and would be able to include N::f
in the candidate list despite the lack of declaration. If N::f
had a previous declaration other than the friend
declaration, it would have won the unqualified lookup. )
这篇关于C ++名称查找-来自标准的示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!