gpt4 book ai didi

c++ - 应用了非限定名称查找而不是依赖于参数的名称查找

转载 作者:太空狗 更新时间:2023-10-29 20:25:30 25 4
gpt4 key购买 nike

考虑标准 sec 3.4.1/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)
}
};
}

f(a) 是后缀表达式。编译器如何确定 f(a) 不是函数调用?我想知道什么时候我们没有像 f previously declared of typedef int f 这样的错误;如以下示例所示:

#include <stdio.h>
typedef int foo; //error: previous declaration of ‘typedef int foo’
class B
{
public:
friend void foo(B b){ printf("3"); } //error: ‘void foo(B)’ redeclared as different kind of symbol

static const int c=42;
};

int main(){ }

最佳答案

(在我的 C++11 文档版本中,示例显示在 3.4.1/3 中)。

3.4.1/3 明确指出,出于解析的目的,为了执行初始确定这是后缀表达式还是函数调用,通常 执行名称查找。 “通常”意味着查找按照 3.4.1 的其余部分所述执行,并且在该初始阶段不使用 ADL。 3.4.1/3 明确指出“3.4.2 中的规则对表达式的句法解释没有影响。” (3.4.2 是 ADL)。

在此示例中,在解析 f(a) 时,通常的查找用于查找名称 f。它找到了全局 typedef-name ::f 而没有别的。这意味着 f(a) 被视为后缀表达式(强制转换),而不是函数调用。请注意,A 中函数 f 的友元声明引用 函数 N::f,但它不是在 N 中引入 N::f 的声明。由于 N::f 函数未在 N 中显式声明(它在 N 中不可见),因此通常的查找不会看到它。它只看到全局 ::f,这是一个 typedef 名称。

如果您希望通过通常的名称查找来找到第一个示例中的函数,您必须在 N 中显式声明该函数

typedef int f;
namespace N
{
struct A; // <- added
void f(A &); // <- added

struct A
{
friend void f(A &);
...

现在 N::f 的声明在 N 中可见。现在,通常的名称查找会找到 N::f 并从一开始就将 f(a) 视为函数调用。

您的第二个示例与第一个示例严重不同。那里没有额外的 namespace 。因为 B 中的友元函数声明引用全局 ::foo 并声明 foo 是一个函数。但是全局 ::foo 已经声明为 typedef-name。这种矛盾正是导致错误的原因。

(有趣的是,标准的 C++03 版本在 3.4.1/3 中包含一个示例,它基本上等同于您的第二个示例。即标准中的示例格式不正确。报告为 Defect #139标准。)

关于c++ - 应用了非限定名称查找而不是依赖于参数的名称查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23820709/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com