Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 直接列表初始化成功编译,但正常的直接初始化失败,原因是什么?_C++_Initialization_Overload Resolution - Fatal编程技术网

C++ 直接列表初始化成功编译,但正常的直接初始化失败,原因是什么?

C++ 直接列表初始化成功编译,但正常的直接初始化失败,原因是什么?,c++,initialization,overload-resolution,C++,Initialization,Overload Resolution,例如,代码如下所示: struct A { A(int); }; struct B { B(A); }; int main() { B b{{0}}; // OK B c({0}); // error } 错误消息如下: f.cc: In function 'int main()': f.cc:7:9: error: call of overloaded 'B(<brace-enclosed initializer list>)' is ambiguous

例如,代码如下所示:

struct A { A(int); };
struct B { B(A);   };

int main()
{
    B b{{0}}; // OK
    B c({0}); // error
}
错误消息如下:

f.cc: In function 'int main()':
f.cc:7:9: error: call of overloaded 'B(<brace-enclosed initializer list>)' is ambiguous
  B c({0}); // error

         ^
f.cc:7:9: note: candidates are:
f.cc:2:12: note: B::B(A)
 struct B { B(A);   };
        ^
f.cc:2:8: note: constexpr B::B(const B&)
 struct B { B(A);   };
        ^
f.cc:2:8: note: constexpr B::B(B&&)
f.cc:在函数“int main()”中:
f、 cc:7:9:错误:重载的“B()”的调用不明确
bc({0});//错误
^
f、 抄送:7:9:注:候选人为:
f、 抄送:2:12:注:B::B(A)
结构B{B(A);};
^
f、 抄送:2:8:注意:constexpr B::B(const B&)
结构B{B(A);};
^
f、 抄送:2:8:注:constexpr B::B(B&&)

根据最新的官方标准C++14,您的第一次初始化并不含糊。[over.match.list]:

由于不存在初始值设定项列表构造函数,我们进入“第二阶段”。现在考虑[Bo.Best.ICS] / 4:

我们的元素是
{0}
。因此这不允许复制构造函数的(用户定义的)转换
{0}
->
A
。显然,如果我们不在[over.match.list]的第二阶段,这不适用,因此对于您的
bc({0})
示例,
c
不会发生列表初始化,并且会考虑这两个构造函数


CWG第1467期 第一次初始化与第二次初始化一样不明确。编译器还没有实现CWG——它的解决方案删除了上面引用的要点(4.5)。
请参阅,哪些选项选择恢复更改:

这项决议提出了一些似是而非的构想 格式不正确。比如说,

struct A { A(int); };
struct B { B(A); };
B b{{0}};
这现在是不明确的,因为文本不允许用户定义 已从中删除
B
的复制和移动构造函数的转换 13.3.3.1[超过最佳ics]第4段

“文本”是上述要点。理查德·史密斯提出以下措辞:

对于非类类型,我们允许从单个项列表进行初始化 仅当列表中的元素本身不是 清单(13.3.3.1.5[超过ics清单]项目符号9.1)的类似规则 本例将在第13.3.3.1节[over.best.ics]中添加该项目符号 第4段,但仅在初始值设定项本身为 初始值设定项列表

第二阶段 13.3.1.7[超过匹配列表]当初始值设定项列表只有一个元素 它本身是一个初始值设定项列表,其中目标是 构造函数
X
,并且转换为 至
X
或参考(可能符合cv条件)
X


由于初始值设定项
{0}
本身就是一个初始值设定项列表,因此该要点将使您的第一次初始化再次格式良好。

是的,它应该是公共的。我已经改变了,谢谢!令人惊讶的是,这失败了,即使我删除了B的复制和移动构造函数:编译错误消息相当令人费解,它与已删除的函数是不明确的。@ChrisBeck已删除的函数参与重载解析,因此删除它们没有什么区别B({{{0}}});我不知道为什么。也许是伏都教?我认为构造
{}
的大括号形式从不采用初始值设定项列表,但paren版本
()
总是采用,即使没有初始值设定项列表构造函数。这个答案提供了一些信息,但不是一个确定的答案。