我编写了以下程序来澄清我的使用声明
概念。但令人惊讶的是,该代码使用 gcc 和 msvc 编译,但被 clang 拒绝。
namespace X
{
struct type {};
}
namespace Y
{
using type = int;
}
using X::type;
using Y::type;
int main()
{
auto i = sizeof(type); //gcc and msvc accepts this but clang rejects this
}
正如你所看到的,上面的程序是用 gcc 和 msvc 编译的,但是 clang 说:
<source>:13:21: error: reference to 'type' is ambiguous
auto i = sizeof(type);
^
<source>:10:10: note: candidate found by name lookup is 'type'
using Y::type;
^
<source>:9:10: note: candidate found by name lookup is 'type'
using X::type;
^
<source>:13:21: error: reference to 'type' is ambiguous
auto i = sizeof(type);
^
<source>:10:10: note: candidate found by name lookup is 'type'
using Y::type;
^
<source>:9:10: note: candidate found by name lookup is 'type'
using X::type;
^
我的问题是根据标准什么是正确的行为。这是正确的编译器。
最佳答案
C++23 之前版本
该程序格式错误(请参阅 gcc bug ),因为 using-declaration
是一个声明,因此它必须遵循声明规则。特别是,给定的两个 using-declaration
声明了一个名为 type
的类型(在全局命名空间),指两种不同的类型 X::type
和 Y::type=int
。
接下来,不能有多个具有相同名称的类型声明(在同一范围内)引用两种不同类型。下面使用 C++ 标准更详细地解释了这一点:
同样来自using declaration's documentation :
Since a using-declaration is a declaration, the restrictions on declarations of the same name in the same declarative region also apply to using-declarations.
(强调我的)
下一步,basic.scope.declarative防止引用两种不同类型的同名声明(您的示例就是这种情况):
Given a set of declarations in a single declarative region, each of which specifies the same unqualified name,
- they shall all refer to the same entity, or all refer to functions and function templates; or
- exactly one declaration shall declare a class name or enumeration name that is not a typedef name and the other declarations shall all refer to the same variable, non-static data member, or enumerator, or all refer to functions and function templates; in this case the class name or enumeration name is hidden ([basic.scope.hiding]).
(强调我的)
由于 type
引用了 2 个不同的实体,因此该程序格式错误。
检验上述结论
另请注意,除了上面引用的引用资料之外,您还可以通过在命名空间 中将
,您会注意到我们收到了预期的错误。 demo :using type = int;
替换为 struct type{};
来测试上述结论Y
namespace X
{
struct type{};
}
namespace Y
{
struct type{};
}
using X::type;
using Y::type; //NOT ALLOWED since same name "type" refers to different structs
此外,如果您将上述程序更改为将 type
定义为与 int
相同的类型,那么程序将正常工作,因为这次名称引用相同的类型 int
。 demo
namespace X
{
using type= int ;
}
namespace Y
{
using type= int;
}
using X::type;
using Y::type; //ALLOWED since "type" refer to same type int
这是 gcc 错误:
GCC accepts invalid program with multiple using declarations
C++23
该程序在 C++23 中也是格式错误,但现在由于语句 auto i = sizeof(type);
而不是 使用 Y::类型;
。
来自 C++23 的[namespace.udecl]:
If a declaration named by a using-declaration that inhabits the target scope of another declaration potentially conflicts with it (6.4.1), and either is reachable from the other, the program is ill-formed. If two declarations named by using-declarations that inhabit the same scope potentially conflict, either is reachable from the other, and they do not both declare functions or function templates, the program is ill-formed.
[Note 4 : Overload resolution possibly cannot distinguish between conflicting function declarations. — end note]
(强调我的)
关于c++ - 使用声明可以在 gcc 和 msvc 中编译,但在 clang 中被拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76099741/