24
#include <iostream>
using namespace std;

struct test
{
    test(){cout<<"class"<<endl;}
};
void test(){cout<<"function"<<endl;}

int main()
{
    test();
    return 0;
}

输出:

function  

(VS2013 和 gcc 4.8.1)

为什么选择功能?不是模棱两可吗?

4

3 回答 3

22

这称为名称隐藏并在

3.3 范围[basic.scope]

3.3.1 声明性区域和范围 [basic.scope.declarative]

4) 给定单个声明区域中的一组声明,每个声明都指定相同的非限定名称
——它们都应引用相同的实体,或都引用函数和函数模板;或
— 恰好一个声明应声明不是 typedef 名称的类名或枚举名,而其他声明应全部引用相同的变量或枚举数,或全部引用函数和函数模板;在这种情况下,类名或枚举名是隐藏的(3.3.10)。[...]

强调我的。

请注意,更改声明顺序不会影响结果:

void test(){cout<<"function"<<endl;}

struct test
{
    test(){cout<<"class"<<endl;}
};

int main()
{
    test();
    return 0;
}

仍然打印出来function

如果不明显,请不要这样做:)

于 2014-10-13T14:15:44.587 回答
9

从 N3485 §3.3.10 [basic.scope.hiding]/2 开始:

类名 (9.1) 或枚举名 (7.2) 可以被同一范围内声明的变量、数据成员、函数或枚举数的名称隐藏。

因此,函数优先于类。

正如评论中提到的,该类仍然可以通过classorstruct关键字访问。如果该类具有优先权,则该功能将无法访问。

于 2014-10-13T14:15:35.007 回答
-4

我不确定前面的任何一个回答都是您特定实例的“为什么”。

不要误会我的意思;它们是真实而准确的。

我只是觉得它更简单。

在您的示例中,您从不实例化结构。

换句话说,你声明了它,但你从未使用过它。

由于您从未引用过它,因此永远不会调用它。

名称优先级等在这里并不真正适用,因为您从未实例化该结构。

希望这可以帮助,

-约翰

于 2014-10-13T17:14:30.093 回答