Fed*_*dor 9 c++ initializer-list language-lawyer overload-resolution
在下面的程序中,structC有两个构造函数:一个来自std::initializer_list<A>,另一个来自std::initializer_list<B>。然后使用以下命令创建该结构的对象C{{1}}:
#include <initializer_list>
struct A {
int i;
};
struct B {
constexpr explicit B(int) {}
};
struct C {
int v;
constexpr C(std::initializer_list<A>) : v(1) {}
constexpr C(std::initializer_list<B>) : v(2) {}
};
static_assert( C{{1}}.v == 1 );
Run Code Online (Sandbox Code Playgroud)
由于只能A从 隐式构造聚合int,因此可以预期这C(std::initializer_list<A>)是首选并且程序成功。在 Clang 中确实如此。
然而海湾合作委员会抱怨:
error: call of overloaded 'C(<brace-enclosed initializer list>)' is ambiguous
note: candidate: 'constexpr C::C(std::initializer_list<B>)'
note: candidate: 'constexpr C::C(std::initializer_list<A>)'
Run Code Online (Sandbox Code Playgroud)
MSVC 也是如此:
error C2440: '<function-style-cast>': cannot convert from 'initializer list' to 'C'
note: No constructor could take the source type, or constructor overload resolution was ambiguous
Run Code Online (Sandbox Code Playgroud)
演示: https: //gcc.godbolt.org/z/joz91q4ed
这里哪个编译器是正确的?
措辞可能更清晰(这并不奇怪),但GCC 和 MSVC在这里是正确的:相关规则 ([over.ics.list]/7) 仅检查
\n\n\n\n
X重载解析 [\xe2\x80\xa6] 选择单个最佳构造函数 [\xe2\x80\xa6] 来执行参数初始值设定项列表中类型的对象的初始化
B因此from的初始化格式错误这一事实{1}是无关紧要的。
有几个这样的地方,隐式转换序列比实际初始化更自由,导致某些情况不明确,即使某些可能性实际上无法工作。如果程序员感到困惑并认为这些未遂事件之一实际上是更好的匹配,则\xe2\x80\x99s是报告歧义的一个功能。
\n| 归档时间: |
|
| 查看次数: |
190 次 |
| 最近记录: |