mal*_*lat 10 c++ gcc-warning c++11
我正在尝试将旧的 C++03 代码库迁移到 C++11。但我无法理解 gcc 在以下情况下警告我的内容:
\n% g++ -std=c++03 t.cxx\n% g++ -std=c++11 t.cxx\nt.cxx: In function \xe2\x80\x98int main()\xe2\x80\x99:\nt.cxx:8:21: warning: converting to \xe2\x80\x98A\xe2\x80\x99 from initializer list would use explicit constructor \xe2\x80\x98A::A(int)\xe2\x80\x99\n 8 | int main() { B b = {}; }\n | ^\nt.cxx:8:21: note: in C++11 and above a default constructor can be explicit\nRun Code Online (Sandbox Code Playgroud)\nstruct A {\n explicit A(int i = 42) {}\n};\nstruct B {\n A a;\n};\n \nint main() {\n B b = {};\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n我在这里想做的只是基本的零初始化。这对于 C++03 似乎是合法的,但我无法理解如何在 C++11 中表达等价物。
\n作为参考,我正在使用:
\n% g++ --version\ng++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0\nRun Code Online (Sandbox Code Playgroud)\n
由于下面解释的原因,给定的程序格式不正确。
B是一个聚合体。由于您没有显式初始化a,因此dcl.init.aggr#5适用:
- 对于非联合聚合,每个不是显式初始化元素的元素都按如下方式初始化:
5.2 否则,如果元素不是引用,则从空初始化器列表([dcl.init.list]) 复制初始化该元素。
这意味着它a是从空的初始值设定项列表复制初始化的。换句话说,就好像我们在写:
A a = {}; // not valid see reason below
Run Code Online (Sandbox Code Playgroud)
现在我们进入dcl.init.list#3.5:
否则,如果初始值设定项列表没有元素并且 T 是具有默认构造函数的类类型,则该对象是值初始化的。
这意味着该对象将被初始化。
现在进行值初始化:
对 T 类型的对象进行值初始化意味着:
- 如果 T 是(可能是 cv 限定的)类类型 ([class]),则
- 如果 T 没有默认构造函数 ([class.default.ctor]) 或用户提供或删除的默认构造函数,则该对象是默认初始化的;
所以我们进入默认初始化:
如果 T 是一个(可能是 cv 限定的)类类型 ([class]),则考虑构造函数。枚举适用的构造函数 ([over.match.ctor]),并通过重载选择初始化程序 () 的最佳构造函数分辨率([over.match])。使用空参数列表调用如此选择的构造函数来初始化对象。
最后来自over.match.ctor:
当类类型的对象被直接初始化、从相同或派生类类型 ([dcl.init]) 的表达式复制初始化或默认初始化时,重载决策会选择构造函数。对于不在复制初始化上下文中的直接初始化或默认初始化,候选函数是正在初始化的对象的类的所有构造函数。 对于复制初始化(包括复制初始化上下文中的默认初始化),候选函数是该类的所有转换构造函数 ([class.conv.ctor])。 参数列表是初始化器的表达式列表或赋值表达式。
这意味着只有转换因子才是候选者。并且由于A::A(int)是显式的,所以它不是转换因子,因此候选集是空的并且program( A a ={};)是格式错误的。
从本质上讲,失败的原因是A a = {};格式不正确。
为了解决这个问题,我们可以将A{}orA{0}作为列表中的初始化器传递,如下所示:
B b = { A{} }; //ok now
B c = { A{0} }; //also ok
Run Code Online (Sandbox Code Playgroud)
工作演示。
A a{};请注意,另一方面,写作格式良好,因为这是一个直接初始化上下文,因此它是direct-list-initialization。
| 归档时间: |
|
| 查看次数: |
2537 次 |
| 最近记录: |