C++11中的统一初始化和默认构造函数参数

3

我正在学习 C++11 的新特性——统一初始化。我写了一个小程序:

#include <iostream> 
using namespace std;

class C {
public:
    C(int a = 1, int b = 2) : a_{a}, b_{b}, n{0,1,2,3,4} {};
    int n[5];
    int a_,b_;

};

int main()
{
    C c = C{}; // should call C(int a = 1, int b = 2) with default arg.
    cout << c.a_ << "  " << c.b_ << endl;
    return 0;
}

然而,我得到了意外的结果0 0。换句话说,所有东西都被初始化为零。这种情况可能发生的唯一方式是:1.隐式默认构造函数被调用,或者2.初始化没有正确执行。(3.编译器???)
为什么我会得到意外的结果?在C++11中使用统一初始化的构造函数语法是否有任何更改?
编辑:使用最新的Intel编译器:
1>------ Rebuild All started: Project: Unif_Init (Intel C++ 13.0), Configuration: Debug Win32 ------
1>  Source.cpp
1>  xilink: executing 'link'
1>  xilink: executing 'link'
1>  Unif_Init.vcxproj -> C:\Users\alex\documents\visual studio 2012\Projects\Unif_Init\Debug\Unif_Init.exe
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

1
什么编译器?我用gcc无法复现。 - Jesse Good
@JesseGood 英特尔 C++ 编译器 13 - newprint
1个回答

3
那是编译器中的错误。 C{} 调用默认构造函数创建一个临时对象,并用其来复制初始化对象 c。 显然,C(int a = 1, int b = 2) 是一个默认构造函数,因此应该使用它。将初始化顺序切换为类中声明的顺序是否有帮助(可能不会,仅猜测)?似乎 intel 编译器未将具有默认参数的构造函数视为默认构造函数。
C(int a = 1, int b = 2) : n{0,1,2,3,4}, a_{a}, b_{b} {};

尝试了你的版本,结果一样。 除此之外,我刚刚尝试了 int* pi = new int[4] {1,2,3,4}; 并且得到了错误 1>Source.cpp(18): error : expected a ";" 1> int* pi = new int[4] {1,2,3,4};//C++09 所以看起来 Intel 编译器不完全符合 C++11,并且存在一些错误。否则,它是最好的编译器。 - newprint
1
@JesseGood:「复制初始化对象」这并不是复制初始化对象。 - Nicol Bolas
据我所知,该代码将调用默认构造函数创建一个临时对象,然后调用移动构造函数将临时对象移动到“c”。我认为这被称为“复制初始化”,我错了吗? - Jesse Good
@JesseGood:你所描述的是复制初始化,但实际上并不是。它执行的是直接列表初始化。这里没有涉及到复制。 - Nicol Bolas
@NicolBolas: 我觉得这可能是因为我的措辞不当。是的,C{} 是直接列表初始化,但我说的是 C c = C{}; 这行代码,其中 C{} 初始化一个临时对象,然后用它来拷贝初始化 c(我已经更新了措辞)。 - Jesse Good

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接