【问题标题】:Elaborated type specifier in type alias类型别名中的详细类型说明符
【发布时间】:2016-10-29 10:48:12
【问题描述】:

为什么下面的代码没有硬错误?类型别名和类名完全一致(编译器clang):

using S = struct S;

struct S {};

S s;

int main()
{
}

以下代码中的变量定义中究竟使用了哪个名称(符号或类型别名)?

using S = struct S {};

int main()
{
    S s;
}

【问题讨论】:

  • 因为C和它的typedef struct S {} S;
  • using S = struct S; 不隐藏,但 重新定义 S 既是 typedef 名称又是类名称(具有两个属性的单个名称)。你会经常听到有人说using S = struct S; 引入了两个名称,C++ 会搜索多个“符号空间”,但在 C++ 中不是这样。可以在open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#407 找到对此的深刻讨论。

标签: c++ c++11 types language-lawyer


【解决方案1】:

下面的代码使S 成为名为@9​​87654322@ 的struct 的别名。 using S 将名称 S 重新定义为 struct S 的别名。

using S = struct S;

下面的行定义了struct S

struct S {};

下面的声明使用S 作为S 的别名,由使用

S s;

至少可以说,这类似于

using K = struct S;

struct S { S(){ std::cout << "Constructed!\n"; } };

K s;

int main()
{    }

代码将打印出来:

Constructed!

基本上,名称K 将替换为struct S


对于您的第二个示例,它本质上与 C 的 typedef 相同:

typedef struct C {} C;

这在 C++ 中简直是多余的

【讨论】:

    【解决方案2】:
    1. 第一个是 C 的保留,其中标记命名空间(结构 / 联合 / 枚举)与类型命名空间(typedef 和内置类型)完全分离。
      在 C++ 中,该规则是宽松的,因此如果 typename-namespace 中没有任何内容,则会自动搜索 tag-namespace。

    2. 通过考虑第一个的答案来回答第二个:
      类型名已找到。

    【讨论】:

    • WRT 1. 所以键入别名函数就像#define?只是文本替换?
    • 不太像那样,那么就不会有两个稍微独立的命名空间。无论如何,#define 是邪恶的。
    • using S = struct S; 在两个不同的查找表中引入了两个名称(从编译器的角度来看)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多