c – 总是用{}初始化对象是好习惯吗?
作者:互联网
使用新的{}语法初始化对象,如下所示:
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.
这是一个好习惯吗?有没有办法避免这样的问题?
解决方法:
坦率地说,各种初始化技术的微妙之处使得很难说任何一种练习都是“好习惯”.
正如评论中所提到的,Scott Meyers在Modern Effective C中详细讨论了大括号初始化.他在他的博客上对此事做了进一步的评论,例如here和here.在第二篇文章中,他最后明确表示他认为C初始化变幻莫测只是糟糕的语言设计.
正如101010的回答中所提到的,支撑初始化有好处.在我看来,防止隐性缩小是主要的好处. “最令人烦恼的解析”问题当然是一个真正的好处,但它是微不足道的 – 在我看来,在大多数情况下,一个不正确的int a();而不是int a;可能会在编译时捕获.
但至少有两个主要缺点:
>在C 11和C 14中,auto总是从大括号初始化器中推导出std :: initializer_list.在C17中,如果初始化列表中只有一个元素,并且未使用=,则自动推断该元素的类型;多个元素的行为没有变化(请参阅上面链接的第二篇博文,以获得更清晰的解释,并附带示例.)(编辑:正如TC在下面的评论中所指出的,我对使用大括号初始化的自动的C 17规则的理解是仍然不太正确.)所有这些行为都有点令人惊讶,并且(在我和Scott Meyers的观点中)令人讨厌和困惑.
> 101010的第三个列出的好处,即初始化列表构造函数优于所有其他构造函数,实际上是一个缺点,也是一个好处.你已经提到过std :: vector< int>的行为了. vi {5,1};熟悉vector的旧的两元素构造函数的人很惊讶. Scott Meyers列出了Effective Modern C中的其他一些例子.就个人而言,我发现这比自动扣除行为更糟糕(我通常只使用自动复制初始化,这使得第一个问题相当容易避免).
编辑:事实证明,愚蠢的编译器实现决策有时可能是another reason to use brace-initialization(尽管真正的#undef方法可能更正确).
标签:c,c11,initializer-list 来源: https://codeday.me/bug/20190722/1503878.html