使用新的{}语法初始化对象:
int a { 123 };
有好处 - 您不会声明函数而不是错误地创建变量。我甚至听说应该习惯这样做。但看看会发生什么:
// I want to create vector with 5 ones in it:
std::vector<int> vi{ 5, 1 }; // ups we have vector with 5 and 1.
那是这个好习惯吗?有没有办法避免这样的问题?
答案 0 :(得分:5)
使用list initialization初始化对象 在适用的地方应该是首选,因为:
其他好处 list-initialization限制允许的隐式缩小 转换。
特别禁止:
long double
转换为double
或转换为float
并从double
转换为float
,除非来源是
不会发生常量表达和溢出。现在关于你的例子,我会说知识带来力量。有一个特定的构造函数用于生成5个向量(即std::vector<int> vi( 5, 1);
)。
答案 1 :(得分:4)
Frankly, the subtleties of the various initialization techniques make it difficult to say that any one practice is a "good habit."
As mentioned in a comment, Scott Meyers discusses brace-initialization at length in Modern Effective C++. He has made further comments on the matter on his blog, for instance here and here. In that second post, he finally says explicitly that he thinks the morass of C++ initialization vagaries is simply bad language design.
As mentioned in 101010's answer, there are benefits to brace-initialization. The prevention of implicit narrowing is the main benefit, in my opinion. The "most vexing parse" issue is of course a genuine benefit, but it's paltry--it seems to me that in most cases an incorrect int a();
instead of int a;
would probably be caught at compile time.
But there are at least two major drawbacks:
auto
always deduces std::initializer_list
from a brace-initializer. In C++17, if there's only one element in the initialization list, and =
is not used, auto
deduces the type of that element; C++17
rules for auto
with brace initialization is still not quite right.) All of these behaviors are somewhat surprising and (in mine and Scott Meyers' opinions) annoying and perplexing.std::vector<int> vi{ 5, 1 };
is surprising to people familiar with vector
's old two-element constructor. Scott Meyers lists some other examples in Effective Modern C++. Personally, I find this even worse than the auto
deduction behavior (I generally only use auto
with copy initialization, which makes the first issue fairly easy to avoid).EDIT: It turns out that stupid compiler-implementation decisions can sometimes be another reason to use brace-initialization (though really the #undef
approach is probably more correct).