简体   繁体   English

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

[英]How to use C++11 uniform initialization syntax?

I cannot understand when and how to use the new uniform initialization syntax in C++11. 我不明白何时以及如何在C ++ 11中使用新的统一初始化语法。
For example, I get this: 例如,我得到这个:

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

Why does it not work in the second case? 为什么在第二种情况下不起作用? The error is: 错误是:

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

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

And with primitive data, what syntax should I use? 对于原始数据,我应该使用什么语法?

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

The compile error for 的编译错误

// T t{u};
std::string a;
std::string b{a};

Is a combination of four things 是四件事的结合

  • The draft until not long ago said that if T has an initializer list constructor ( std::string has one, taking char elements), that the initializer list is passed itself as an argument. 草案直到不久前才说过,如果T有一个初始化器列表构造函数( std::string有一个采用char元素的构造器),那么初始化器列表将作为参数传递给自己。 So the argument to the constructor(s) is not a , but {a} . 因此,构造函数的参数不是a ,而是{a}

  • The draft says that an initializer list initializing a reference is done not by direct binding, but by first constructing a temporary out of the element in the initializer list, and then binding the target reference to that temporary. 草案说,初始化引用的初始化列表不是通过直接绑定来完成的,而是先从初始化列表中的元素构造一个临时对象,然后将目标引用绑定到该临时对象。

  • The draft says that when initializing a reference by an initializer list, when the initialization of the reference is not direct binding, that the conversion sequence is a user defined conversion sequence. 草案说,当通过初始化列表初始化参考时,当参考的初始化不是直接绑定时,转换序列就是用户定义的转换序列。

  • The draft says that when passing the initializer list itself when considering constructors of class X as candidates in an overload resolution scenario in a context like the above, then when considering a first constructor parameter of type "reference to cv X" (cv = const / volatile) - in other words highly likely a copy or move constructor, then no user defined conversions are allowed. 草案说,当像上面那样在超载解决方案中将类X构造函数视为候选时,传递初始值设定项列表本身时,然后考虑“引用cv X”类型的第一个构造函数参数(cv = const /易失性)-换句话说,很可能是复制或移动构造函数,则不允许用户定义的转换。 Otherwise, if such a conversion would be allowed, you could always run in ambiguities, because with list initialization you are not limited to only one nested user defined conversion. 否则,如果允许进行这种转换,则始终可能会模棱两可,因为使用列表初始化时,您不仅限于一个嵌套的用户定义转换。

The combination of all the above is that no constructor can be used to take the {a} . 以上所有内容的组合是,不能使用任何构造函数来使用{a} The one using initializer_list<char> does not match, and the others using string&& and const string& are forbidden, because they would necessitate user defined conversions for binding their parameter to the {a} . 一个使用initializer_list<char>不匹配,而另一个使用string&&const string&则被禁止,因为它们将需要用户定义的转换才能将其参数绑定到{a}

Note that more recent draft changed the first rule: They say that if no initializer list constructor can take the initializer list, that then the argument list consists of all the elements of the initializer list. 请注意,最近的草案更改了第一条规则:他们说,如果没有初始化器列表构造函数可以使用初始化器列表,则参数列表将包含初始化器列表的所有元素 With that updated rule, your example code would work fine. 使用该更新的规则,您的示例代码将可以正常工作。

The first example is supposed to work, calling the copy constructor. 第一个示例应该可以工作,调用复制构造函数。 If you're using GCC, this has been fixed in 4.6. 如果您使用的是GCC,则该问题已在4.6中修复。

The last examples have a slight non stylistic difference. 最后的示例在​​风格上略有不同。

int i = 5.0;   // fine, stores 5
int i{5.0};    // won't compile!
int i = {5.0}; // won't compile!

The difference is that uniform initialization syntax does not allow narrowing conversions. 不同之处在于统一的初始化语法不允许缩小转换范围。 You may want to take this into consideration when choosing between them. 在它们之间进行选择时,您可能需要考虑这一点。

It doesn't work because you forgot the semicolon: 它不起作用,因为您忘记了分号:

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

Otherwise this syntax is fine, and it calls the copy constructor. 否则,此语法就可以了,它会调用复制构造函数。

For the second question, use int i{5}; 对于第二个问题,请使用int i{5}; if you want to be uniform, though int i = 5; 如果要统一,尽管int i = 5; is probably more readable. 可能更具可读性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C ++ 11构造函数和运算符的统一初始化= - C++11 Uniform initialization for constructor and operator= C ++ 11统一初始化和函数重载 - C++11 Uniform Initialization and function overloading C ++ 11中的统一初始化语法 - Unified initialization syntax in C++11 c ++ 11统一初始化不适用于clang ++ - c++11 Uniform initialization does not work with clang++ Eclipse格式不正确的C ++ 11统一初始化 - C++11 Uniform Initialization Formatted Incorrectly by Eclipse &#39;结构初始化程序中的多余元素&#39;错误与C ++ 11统一初始化 - 'Excess elements in struct initializer' error with C++11 uniform initialization C ++ 11统一初始化:字段初始化器不是常量 - C++11 uniform initialization: Field initializer is not constant C ++ 11统一初始化(即列表初始化)不与继承一起编译 - C++11 Uniform initialization (i.e. list initialization) doesn't compile with inheritance 我可以使用C ++ 11大括号初始化语法来避免为简单聚合声明普通构造函数吗? - Can I use the C++11 brace initialization syntax to avoid declaring trivial constructors for simple aggregates? 如何在 class 构造函数中使用 C++11 随机引擎和均匀分布? - How do I use C++11 random engine and uniform distribution in class constructor?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM