[英]Type alias with same name as type
Is it valid C++? C++ 有效吗?
#include <iostream>
class Test {
struct Inner {
};
public:
using Inner = struct Inner; // Alias with same name as type
};
int main(int argc, const char * argv[]) {
static_assert(std::is_pod<Test::Inner>::value, "");
return 0;
}
Compile fine with clang but not with GCC / Visual C++ ("Inner is private..." error message)使用 clang 可以正常编译,但不能使用 GCC / Visual C++(“内部是私有的...”错误消息)
GCC and Visual C++ are correct. GCC 和 Visual C++ 是正确的。
Indeed you can use using
to in effect change the access of a member, eg实际上,您可以使用using
来有效地更改成员的访问权限,例如
using Inner_ = Inner;
with和
static_assert(std::is_pod<Test::Inner_>::value, "");
in the function.在 function。
But in the case where the type alias has the same name as the member, C++ requires that the scope resolution operator looks up the member.但在类型别名与成员同名的情况下,C++ 需要 scope 解析运算符查找成员。 So in your case Test::Inner
refers to the actual member rather than to the using
and compilation should therefore fail as it's private
.因此,在您的情况下, Test::Inner
指的是实际成员而不是using
,因此编译应该失败,因为它是private
。
See https://en.cppreference.com/w/cpp/language/qualified_lookup , and in particular请参阅https://en.cppreference.com/w/cpp/language/qualified_lookup ,尤其是
Qualified lookup within the scope of a namespace N first considers all declarations that are located in N and all declarations that are located in the inline namespace members of N (and, transitively, in their inline namespace members).在命名空间 N 的 scope 内进行的限定查找首先考虑位于 N 中的所有声明以及位于 N 的内联命名空间成员(以及可传递地位于其内联命名空间成员中)的所有声明。 If there are no declarations in that set then it considers declarations in all namespaces named by using-directives found in N and in all transitive inline namespace members of N如果该集合中没有声明,则它会考虑在 N 中找到的使用指令命名的所有命名空间和 N 的所有传递内联命名空间成员中的声明
P1787R6: Declarations and where to find them , merged into C++23 draft, seems to favor Clang's behavior: P1787R6: Declarations and where to find them ,合并到 C++23 草案中,似乎有利于 Clang 的行为:
In certain contexts, only certain kinds of declarations are included.在某些情况下,仅包含某些类型的声明。 After any such restriction, any declarations of classes or enumerations are discarded if any other declarations are found .在任何此类限制之后,如果发现任何其他声明,则丢弃任何类或枚举的声明。 [Note: A type (but not a typedef-name or template) is therefore hidden by any other entity in its scope. — end note] However, if a lookup is type-only , only declarations of types and templates whose specializations are types are considered; [注意:类型(但不是typedef 名称或模板)因此被其 scope 中的任何其他实体隐藏。 - 尾注]但是,如果查找是type-only ,则只有类型和模板的声明,其特化是类型被考虑; furthermore, if declarations of a typedef-name and of the type to which it refers are found, the declaration of the typedef-name is discarded instead of the type declaration.此外,如果找到typedef-name和它所引用的类型的声明,则丢弃typedef-name的声明而不是类型声明。
So the declaration of struct Inner
is discarded, because the alias-declaration is found.所以struct Inner
的声明被丢弃,因为找到了别名声明。 (One can put Inner
into type-only context — Test::struct Inner
— and it will refer to the struct Inner
declaration, per the second part of the paragraph). (可以将Inner
放入仅限类型的上下文中Test::struct Inner
根据本段的第二部分,它将引用struct Inner
声明)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.