使用{}初始化对象是好习惯吗? [英] Is it good habit to always initialize objects with {}?

查看:117
本文介绍了使用{}初始化对象是好习惯吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用新的{}语法初始化对象,如下所示:

Initializing objects with new {} syntax like this:

int a { 123 };

有好处 - 你不会声明一个函数而不是错误地创建一个变量。我甚至听说,应该习惯总是这样做。但看看会发生什么:

has benefit - you would not declare a function instead of creating a variable by mistake. I even heard that it should be habit to always do that. But see what could happen:

// I want to create vector with 5 ones in it:
std::vector<int> vi{ 5, 1 }; // ups we have vector with 5 and 1.

这是好习惯吗?有没有办法避免这种问题?

Is this good habit then? Is there a way to avoid such problems?

推荐答案

坦率地说,各种初始化技术的微妙之处使得很难说任何一个做法是一个好习惯。

Frankly, the subtleties of the various initialization techniques make it difficult to say that any one practice is a "good habit."

正如注释中提到的,Scott Meyers在 Modern Effective C ++ 中详细讨论了括号初始化。他在他的博客上进一步评论了这个问题,例如此处此处。在第二篇文章中,他最后明确地说,他认为C ++初始化变幻莫测的错误只是一种糟糕的语言设计。

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.

正如101010的回答中提到的, -初始化。在我看来,防止隐性缩小是主要的好处。 最麻烦的解析问题当然是一个真正的好处,但它是微不足道 - 在我看来,在大多数情况下,一个不正确的 int a(); 而不是<

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:


  • 在C ++ 11和C ++ 14中, auto 总是推导 std :: initializer_list 。在C ++ 17中,如果初始化列表中只有一个元素,并且 = 不是,则使用 auto 推导出该元素的类型; 多个元素的行为未更改(请参阅以上链接的第二篇博文,以获得更清楚的说明,并附上示例。)(修改 ,我理解 C ++ 17 规则为 auto 与大括号初始化仍然

  • 101010的第三个列出的好处是,初始化列表构造函数是首选的对所有其他建设者,实际上是一个缺点以及一个好处。你已经提到了 std :: vector< int> vi {5,1}; 对于熟悉向量的旧二元素构造函数的人来说是令人惊讶的。 Scott Meyers列出了有效现代C ++ 中的一些其他示例。个人而言,我发现这甚至比 auto 扣除行为(我通常只使用 auto 与复制初始化,这使得第一个问题相当容易避免。)

  • In C++11 and C++14, 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; the behavior for multiple elements is unchanged (See the second blog post linked above for a clearer explanation, with examples.) ( as pointed out by T.C. in a comment below, my understanding of the 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.
  • 101010's third listed benefit, which is that initialization list constructors are preferred to all other constructors, is actually a drawback as well as a benefit. You've already mentioned that the behavior of 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).

编辑:原来,愚蠢的编译器实现决定有时可以使用括号初始化的另一个原因(虽然真的 #undef 方法可能更正确)。

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).

这篇关于使用{}初始化对象是好习惯吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆