我希望使用结构体来包含另一个类型的类型别名,以便进行元编程:
struct Foo {};
struct WithNestedTypeAlias {
using Foo = Foo;
};
那么在模板中,我可以使用 WithNestedTypeAlias::Foo
这样的语法。
据我理解,这个类型别名是合法的,因为它没有改变 Foo
类型的含义。Clang 可以快乐地编译它。
然而,GCC 却报错:
test-shadow-alias.cpp:4:20: error: declaration of ‘using Foo = struct Foo’ [-fpermissive]
using Foo = Foo;
^
test-shadow-alias.cpp:1:8: error: changes meaning of ‘Foo’ from ‘struct Foo’ [-fpermissive]
struct Foo {};
^
现在我感到困惑,因为我明确没有改变struct Foo
的含义。
C++14的正确行为是什么? 我知道我可以通过重命名struct Foo
来解决这个问题,但我想了解GCC的错误是否正确。
注:
已使用clang++ 3.8和gcc 5.4进行测试,但Godbolt表明在更近期的GCC版本中,情况并未发生变化。
我查看了decltype与类成员名称交互会遮挡外部名称,其中变量的名称可能指向外部范围内的变量或类成员。相反,我在这里提出的问题是关于类型别名的。由于
Foo
始终在类作用域内引用::Foo
,因此不存在歧义。我不明白那里的答案如何适用于我的问题。这可能是由于对类型别名实际上是什么的误解所致。
using Foo = ::Foo;
可以解决问题,但我无法解释为什么。 - François Andrieuxusing Foo = struct Foo;
也可以解决这个问题。请注意,等效的typedef struct Foo Foo;
是惯用的 C 代码。 - Oktalist