gpt4 book ai didi

c++ - 列表初始化的重载解析规则是什么

转载 作者:行者123 更新时间:2023-12-01 22:16:17 25 4
gpt4 key购买 nike

这里有一些代码

#include <iostream>
struct A {
A(int) {}
};
struct B {
B(A) {
std::cout<<"0"<<std::endl;
}
B(B const&) {
std::cout << "1" << std::endl;
}
B(B&&) {
std::cout << "2" << std::endl;
}
};
int main() {
B b0{{0}}; // this is ok #1
B b( {0} ); //this is error #2
}

g++ 报告:

main.cpp: In function ‘int main()’:
main.cpp:17:11: error: call of overloaded ‘B(<brace-enclosed initializer list>)’ is ambiguous
B b({ 0 });
^
main.cpp:12:2: note: candidate: B::B(B&&)
B(B&&) {
^
main.cpp:9:2: note: candidate: B::B(const B&)
B(B const&) {
^
main.cpp:6:2: note: candidate: B::B(A)
B(A) {

铿锵报告:

main.cpp:17:4: error: call to constructor of 'B' is ambiguous
B b({ 0 });
^ ~~~~~
main.cpp:6:2: note: candidate constructor
B(A) {
^
main.cpp:12:2: note: candidate constructor
B(B&&) {
^
main.cpp:9:2: note: candidate constructor
B(B const&) {
^
1 error generated.

{0} 将转换为临时对象 A 并选择构造函数 B(A), #1和#2都是“直接构造函数”形式,为什么#1没问题,#2却有3个候选构造函数,而且有歧义?

最佳答案

因为对于#1,[over.best.ics]/4 不允许复制和移动构造函数。 (强调我的):

However, if the target is

  • the first parameter of a constructor or
  • the implicit object parameter of a user-defined conversion function

and the constructor or user-defined conversion function is a candidate by

  • [over.match.ctor], when the argument is the temporary in the second step of a class copy-initialization,

  • [over.match.copy], [over.match.conv], or [over.match.ref] (in all cases), or

  • the second phase of [over.match.list] when the initializer list has exactly one element that is itself an initializer list, and the target is the first parameter of a constructor of class X, and the conversion is to X or reference to cv X,

user-defined conversion sequences are not considered. [ Note: These rules prevent more than one user-defined conversion from being applied during overload resolution, thereby avoiding infinite recursion.  — end note ]

所以区分({...}){{...}}的是语言规则。请注意 ({...}) 情况属于 [over.match.ctor] 但参数不是类复制初始化第二步中的临时参数,因此第一个项目符号不申请。

您可以进一步阅读Issue 2076看到它的目的是在 {{...}} 情况下禁止内部大括号的复制和移动构造函数:

The resolution of issue 1467 made some plausible constructs ill-formed. For example,

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

This is now ambiguous, because the text disallowing user-defined conversions for B's copy and move constructors was removed from 16.3.3.1 [over.best.ics] paragraph 4...

关于c++ - 列表初始化的重载解析规则是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58930321/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com