【问题标题】:typedef and using declaration for same name at same scopetypedef 和 using 声明在同一范围内的同名
【发布时间】:2013-02-13 23:13:21
【问题描述】:

我搜索了 C++11 标准(嗯,n3242 草案)和互联网,但找不到准确的答案。下面的代码可以在 clang 3.2 和 g++ 4.7.2 以及 Visual Studio 2010 上正常编译,但我希望得到一个错误。

#include <iostream>
#include <typeinfo>


typedef int a_t;


namespace a_ns
{
class a_t {};
}


using a_ns::a_t;


int main()
{
    a_t a;
    std::cout << typeid(a).name() << std::endl;
    return 0;
}

内置:

clang -std=c++11 -pedantic -Wall -o a a.cpp -lstdc++
g++ -std=c++11 -pedantic -Wall -o a a.cpp -lstdc++
cl -EHsc -GR a.cpp

clang 和 g++ 生成的可执行文件打印“i”,这似乎表明 a 是 int 类型,并且 typedef 占了上风。 cl 生成的可执行文件打印“class a_ns::a_t”,这似乎表明 Visual Studio 更喜欢 using 声明。

我希望代码不会根据以下标准摘录进行编译。我预计会出现类似于“使用声明的目标与范围内的声明冲突”的错误。

7.1.3.6 类似地,在给定范围内,类或枚举不应使用与在 该范围并引用除类或枚举之外的类型 自己。

7.3.3.1 using-declaration 将名称引入到 using-declaration 出现的声明区域中。

7.3.3.2 每个 using 声明都是一个声明 [...]

标准中可能缺少解释此行为的某些内容(或者我太累了,看不到明显的内容),但我似乎找不到。

谢谢。

【问题讨论】:

    标签: c++ typedef using-declaration


    【解决方案1】:

    没错,您所显示的内容使代码无效。还有 3.3.1p4 也使其无效(参见 7.3.3p13)。

    对于现实测试,我使用 ICC 进行了测试,它按预期拒绝了它。

    【讨论】:

    • 如果main() 的主体为空,那么该程序是否也无效?第 7.1.3/6 段说“在给定的范围内,不应使用 typedef 说明符重新定义在该范围内声明的任何类型的名称以引用不同的类型。 i> [ 示例:class complex { / ... / }; typedef int complex; // error: redefinition — 结束示例 ] "。在问题中,typedef 没有“重新定义”名称。在 using 声明之后移动时,所有编译器都会发出错误。
    • @andy 如果 main 为空,根据我们找到的引用,它也将无效。那么其他引用是否也适用是无关紧要的。通常,class A {}; typedef A A; 会重新定义名称(首先它只是一个类名。然后它也是一个 typedef-name。重新定义名称,因为之后仍然只有一个名称,但它同时具有语法属性。这与 C 模型不同)。
    猜你喜欢
    • 2019-06-22
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-02
    • 1970-01-01
    相关资源
    最近更新 更多