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

时间:2011-09-30 14:45:48

标签: c++ c++11 uniform-initialization

我无法理解何时以及如何在C ++ 11中使用新的统一初始化语法 例如,我明白了:

std::string a{"hello world"}; // OK
std::string b{a};  // NOT OK

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

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

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

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

int i = 5;
int i{5};
int i = {5};

3 个答案:

答案 0 :(得分:20)

的编译错误
// T t{u};
std::string a;
std::string b{a};

是四件事的组合

  • 直到不久前的草案说如果T有一个初始化列表构造函数(std::string有一个,取char个元素),那么初始化列表就会自行传递作为一个论点。所以构造函数的参数不是a,而是{a}

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

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

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

以上所有的组合是没有构造函数可以用来取{a}。使用initializer_list<char>的人不匹配,而使用string&&const string&的其他人则被禁止,因为他们需要用户定义的转化才能将其参数绑定到{a}。< / p>

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

答案 1 :(得分: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!

不同之处在于统一初始化语法不允许缩小转换。在选择它们时,您可能需要考虑这一点。

答案 2 :(得分:4)

它不起作用,因为你忘记了分号:

std::string b{a};
               ^^^

否则这种语法很好,它会调用复制构造函数。

对于第二个问题,如果您想要统一,请使用int i{5};,但int i = 5;可能更具可读性。