转换为‘ a’从初始化器列表中将使用显式构造函数‘ a :: A(int)’
我正在尝试将旧的C ++ 03代码库迁移到C ++ 11。但是我无法理解在下种情况下警告我的GCC是什么:
% g++ -std=c++03 t.cxx
% g++ -std=c++11 t.cxx
t.cxx: In function ‘int main()’:
t.cxx:8:21: warning: converting to ‘A’ from initializer list would use explicit constructor ‘A::A(int)’
8 | int main() { B b = {}; }
| ^
t.cxx:8:21: note: in C++11 and above a default constructor can be explicit
struct A {
explicit A(int i = 42) {}
};
struct B {
A a;
};
int main() {
B b = {};
return 0;
}
我在这里要做的只是基本的零初始化。对于C ++ 03来说,这似乎是合法的,但是我无法理解如何在C ++ 11中表达等效物。
作为参考,我正在使用:
% g++ --version
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
I am trying to migrate an old C++03 codebase to C++11. But I fail to understand what gcc is warning me about in the following case:
% g++ -std=c++03 t.cxx
% g++ -std=c++11 t.cxx
t.cxx: In function ‘int main()’:
t.cxx:8:21: warning: converting to ‘A’ from initializer list would use explicit constructor ‘A::A(int)’
8 | int main() { B b = {}; }
| ^
t.cxx:8:21: note: in C++11 and above a default constructor can be explicit
struct A {
explicit A(int i = 42) {}
};
struct B {
A a;
};
int main() {
B b = {};
return 0;
}
All I am trying to do here is a basic zero initialization. It seems to be legal for C++03, but I fail to understand how to express the equivalent in C++11.
For reference, I am using:
% g++ --version
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于下面的原因,给定的程序是 。
C ++ 20
b
是汇总。由于您不是明确初始化a
, dcl.init.aggr#5 适用:这意味着
a
是从一个空的初始化器列表中复制初始化。换句话说,就像我们在写作一样:现在我们进入 dcl.init.list#3.5 :
这意味着该对象的值将初始化。
现在到值初始化:
因此,我们进入默认初始化:
最后来自 over.match.ctor.ctor :
这意味着只有转换CTOR才是候选人。而且由于
a :: a(int)
是明确的,因此它不是转换的ctor,因此候选人集为空,并且程序(a a a = {};
)是不构建的。本质上,失败的原因是
a a = {};
是错误的。解决此问题的解决方案
,我们可以通过
a {}
或a {0}
作为列表中的初始化器,如下所示:工作演示。
请
注意,另一方面,编写
a a {};
,因为这是一个直接的启动上下文,因此它是 direct-list-list-initialization 。The given program is ill-formed for the reason(s) explained below.
C++20
B
is an aggregate. Since you're not explicitly initializinga
, dcl.init.aggr#5 applies:This means that
a
is copy initialized from an empty initializer list. In other word, it is as if we're writing:Now we move onto dcl.init.list#3.5:
This means that the object will be value initialized.
Now to value initialize:
So we move onto default initialize:
Finally from over.match.ctor:
This means that only the converting ctor are candidates. And since
A::A(int)
is explicit, it is not a converting ctor and thus there the set of candidates is empty and the program(A a ={};
) is ill-formed.Essentially, the reason for the failure is that
A a = {};
is ill-formed.Solution
To solve this, we can pass
A{}
orA{0}
as the initializer inside the list as shown below:Working demo.
Note
Note that writing
A a{};
on the other hand is well-formed as this is a direct-initialization context and so it is direct-list-initialization.