Fed*_*dor 7 c++ using language-lawyer overload-resolution
在下面的程序中,struct B有两个用户定义的构造函数:一个来自int,另一个来自int&&(显然这不太实用)。并且 的对象B是从左值创建的,它应该明确选择第一个构造函数。thenstruct C是B通过 - 声明继承其构造函数而派生的using,并且 的对象C是从完全相同的左值创建的:
struct B {
B(int) {}
B(int&&) {}
};
int i = 1;
B b(i); //ok everywhere
struct C : B {
using B::B;
};
C c(i); //ok in Clang only
Run Code Online (Sandbox Code Playgroud)
MSVC 在最后一行打印出相当奇怪的错误:
source>(10): error C2668: 'B::B': ambiguous call to overloaded function
<source>(3): note: could be 'B::B(int &&)'
<source>(2): note: or 'B::B(int)'
<source>(10): note: while trying to match the argument list '(int)'
Run Code Online (Sandbox Code Playgroud)
尽管有左值论证。
GCC 错误似乎同意并解释了更多:
source>:13:6: error: use of deleted function 'C::C(int) [inherited from B]'
13 | C c(i);
| ^
<source>:10:14: note: 'C::C(int) [inherited from B]' is implicitly deleted because the default definition would be ill-formed:
10 | using B::B;
| ^
<source>:10:14: error: call of overloaded 'B(int)' is ambiguous
Run Code Online (Sandbox Code Playgroud)
同时Clang接受代码就好了,demo: https: //gcc.godbolt.org/z/oGjzrYEhz
这里是哪个编译器?
在 C++14 中,GCC 拒绝C c(i). 根据C++14:class.inhctor#8
隐式定义的继承构造函数执行该类的一组初始化,这些初始化将由该类的用户编写的内联构造函数执行,该构造函数具有 mem-initializer-list,其中唯一的 mem-initializer 有一个 mem-initializer-id 来命名该类在 using 声明的嵌套名称说明符和下面指定的表达式列表中表示的基类,并且其函数体中的复合语句为空 ([class.base.init])。如果用户编写的构造函数格式错误,则该程序格式错误。表达式列表中的每个表达式的形式为
static_cast<T&&>(p),其中p是相应构造函数参数的名称,T是 的声明类型p。
定义struct C等价于
struct C : B {
C(int p) : B(static_cast<int&&>(p)) {}
C(int&& p) : B(static_cast<int&&>(p)) {}
};
Run Code Online (Sandbox Code Playgroud)
其中的调用B(static_cast<int&&>(p))确实是不明确的。
而在 C++17 标准中,措辞已更改为C++17: class.inhctor.init#1,并且 Clang 根据新规则接受程序是正确的。
| 归档时间: |
|
| 查看次数: |
95 次 |
| 最近记录: |