与类型同名的类型别名
Type alias with same name as type
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;
}
使用 clang 可以正常编译,但不能使用 GCC/Visual C++(“Inner is private...”错误消息)
GCC 和 Visual C++ 是正确的。
您确实可以使用 using
来有效地更改成员的访问权限,例如
using Inner_ = Inner;
和
static_assert(std::is_pod<Test::Inner_>::value, "");
在函数中。
但在类型别名与成员同名的情况下,C++ 要求作用域解析运算符查找成员。因此,在您的情况下,Test::Inner
指的是实际成员而不是 using
,因此编译应该失败,因为它是 private
.
参见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). 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
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; 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.
因此 struct Inner
的声明被丢弃,因为找到了 alias-declaration。 (可以将 Inner
放入仅限类型的上下文中 - Test::struct Inner
- 根据该段的第二部分,它将引用 struct Inner
声明。
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;
}
使用 clang 可以正常编译,但不能使用 GCC/Visual C++(“Inner is private...”错误消息)
GCC 和 Visual C++ 是正确的。
您确实可以使用 using
来有效地更改成员的访问权限,例如
using Inner_ = Inner;
和
static_assert(std::is_pod<Test::Inner_>::value, "");
在函数中。
但在类型别名与成员同名的情况下,C++ 要求作用域解析运算符查找成员。因此,在您的情况下,Test::Inner
指的是实际成员而不是 using
,因此编译应该失败,因为它是 private
.
参见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). 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
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; 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.
因此 struct Inner
的声明被丢弃,因为找到了 alias-declaration。 (可以将 Inner
放入仅限类型的上下文中 - Test::struct Inner
- 根据该段的第二部分,它将引用 struct Inner
声明。