如何使用C++ 11统一初始化语法?

sma*_*ill 13 c++ uniform-initialization c++11

我无法理解何时以及如何在C++ 11中使用新的统一初始化语法.
例如,我得到这个:

std::string a{"hello world"}; // OK
std::string b{a};  // NOT OK
Run Code Online (Sandbox Code Playgroud)

为什么在第二种情况下不起作用?错误是:

error: no matching function for call to ‘std::basic_string<char>::basic_string(<brace enclosed initializer list>)’    
Run Code Online (Sandbox Code Playgroud)

使用此版本的g ++ g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2.

对于原始数据,我应该使用什么语法?

int i = 5;
int i{5};
int i = {5};
Run Code Online (Sandbox Code Playgroud)

Joh*_*itb 20

编译错误

// T t{u};
std::string a;
std::string b{a};
Run Code Online (Sandbox Code Playgroud)

是四件事的组合

  • 直到不久前的草案说,如果T有一个初始化列表构造函数(std::string有一个,取char元素),初始化列表将自己作为参数传递.所以构造函数的参数不是a,但是{a}.

  • 草案说初始化引用的初始化列表不是通过直接绑定完成的,而是通过首先在初始化列表中构造临时元素,然后将目标引用绑定到该临时.

  • 草案说,当初始化引用初始化列表时,当引用的初始化不是直接绑定时,转换序列是用户定义的转换序列.

  • 草案说当X在类似于上面的上下文中的重载决策场景中考虑类的构造函数作为候选者时传递初始化列表本身时,那么在考虑类型"引用到cv X"的第一个构造函数参数时(cv = const/volatile) ) - 换句话说很可能是复制或移动构造函数,因此不允许用户定义的转换.否则,如果允许这样的转换,您可能总是在歧义中运行,因为使用列表初始化您不仅限于一个嵌套的用户定义转换.

以上所有的组合是没有构造函数可以用来获取{a}.一个使用initializer_list<char>不匹配,其他使用string&&const string&禁止,因为他们将需要用户定义的转换将其参数绑定到{a}.

请注意,更新的草案更改了第一条规则:它们表示如果没有初始化列表构造函数可以获取初始化列表,那么参数列表将包含初始化列表的所有元素.使用该更新的规则,您的示例代码将正常工作.

  • 整洁,历史背景. (2认同)

R. *_*des 10

第一个例子应该可以工作,调用复制构造函数.如果您正在使用GCC,则已在4.6中修复.

最后一个例子略有不同的风格差异.

int i = 5.0;   // fine, stores 5
int i{5.0};    // won't compile!
int i = {5.0}; // won't compile!
Run Code Online (Sandbox Code Playgroud)

不同之处在于统一初始化语法不允许缩小转换.您可能希望在选择它们时考虑到这一点.