【问题标题】:What happens when a class and a function have the same name?当一个类和一个函数同名时会发生什么?
【发布时间】:2014-10-14 01:14:30
【问题描述】:
#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)

为什么选择函数?是不是模棱两可?

【问题讨论】:

  • 我认为编译器选择函数是因为一个类永远不会用它的基名调用。如果你删除了 void test(),你可能会得到一个未定义的函数……它不是模棱两可,因为这两者总是被不同的上下文调用......
  • 检查这个问题,它是类似的:stackoverflow.com/questions/7763802/…@LeonardoBernardini 如果你删除 void test(),你不会得到未定义的函数,因为编译器会创建一个新的测试对象但不会在任何地方分配它.
  • 您可以使用struct test t{}; 语法访问您的班级

标签: c++ ambiguity ambiguous-call


【解决方案1】:

这称为名称隐藏并在

中进行了描述

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

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

【讨论】:

  • 您可能应该指出这是一个 hack,出于 C 兼容性的原因,您可能不想在实际代码中使用它。
  • @JamesKanze 我不知道。
  • 您不知道这是为了与 C 兼容,或者您​​不知道这是一个坏主意:-)。它存在的真正原因是支持 Posix 函数stat(它有一个输出参数struct stat*);在 C 中,您需要 struct,并且在 struct 之后的名称在与其他名称不同的名称空间中查找。 C++ 中有些尴尬的规则试图支持这一点,同时仍然允许使用像 Posix 这样的 C 库。 (而且我确信这在一些早期的规范中有所记载,也许是 ARM。)
【解决方案2】:

来自 N3485 §3.3.10 [basic.scope.hiding]/2:

类名 (9.1) 或枚举名 (7.2) 可以通过变量名、数据成员名、 在同一作用域中声明的函数或枚举器。

因此,函数优先于类。

comments 中所述,该类仍可通过classstruct 关键字访问。如果类优先,则函数将无法访问。

【讨论】:

    【解决方案3】:

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

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

    我只是觉得它更简单。

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

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

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

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

    希望对你有帮助,

    -约翰

    【讨论】:

    • 你应该引用任何来源或文件来推理你的想法,或提供任何证据来证明它是正确的。在这个答案中你没有这样做。
    • 该答案本身甚至不合逻辑:该类从未实例化因为其他答案中引用的优先规则要求调用该函数。如果优先级规则反过来,则将实例化一个临时对象并调用构造函数。所以说“优先级等不适用,因为结构没有实例化”是完全错误的。
    猜你喜欢
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 2012-02-26
    • 2012-07-30
    • 2020-08-22
    • 2017-03-24
    • 1970-01-01
    相关资源
    最近更新 更多