为什么C++有不同的变量初始化方式?

3
自2011年C++标准的修订以来,变量可以通过以下三种不同的方式进行初始化。
int i = 0;
int i (0);
int i {0};

据我所知,这三种不同的初始化方式都具有相同的效果。既然它们都具有相同的效果,为什么不坚持使用第一种初始化方式呢?是否有特殊需要通过在()或{}中包围初始值来初始化变量?

4
对于基本类型而言大部分相同,隐式转换存在差异。但对于其他类型存在很大的区别。std::vector<int> i(0)std::vector<int> i{0} 之间存在差异,而 std::vector<int> i = 0 则会报错。 - Thomas Sablik
3
有很多种方法,但没有一个理由需要拥有超过一个。 - user7860670
2
复制初始化、直接初始化和列表初始化并不总是产生相同的结果。 - Jesper Juhl
2
C++中的初始化是疯狂的 - molbdnilo
2
花括号初始化可以用于初始化非静态数据成员,禁止隐式缩小转换,易于避免令人烦恼的解析。 - Owl66
显示剩余5条评论
3个回答

3

保持不禁止这三种写法的原因是为了维护向后兼容性。

目前已经有大量使用每一种写法的代码投入生产。如果标准发生了变化,那么工作中的代码就需要进行重写,这会导致成本和潜在错误。由于C++委员会非常重视向后兼容性,所以我们陷入了这种情况。尽管如此,它仍然比其他语言(例如Python)要好得多,因为在Python中,从一个小版本到另一个小版本,您需要重写代码来格式化字符串或循环从零到十。

如果可以选择,建议选择{0},这就是所谓的统一初始化方式 :-)


3
这是一个历史性的问题。第一个是 int i = 0;,它来自1970年代早期的C语言。接下来,第一个C++版本推出了一个类似初始化语法的函数,写在这里int i(0);。但由于最令人烦恼的解析歧义,花括号初始化被发明出来。
为了兼容性的原因,所有这些语法仍然有效......

1
int i = 0;
int i (0); //For backward compatibility
int i {0}; //Uniform Initialization

这三种初始化方式存在差异。
int i = 2.2;
int i (2.2);
int i {2.2};

首先,两个值会进行隐式转换,但是int i {0};会因为参数缩小而出现错误/警告。

有关初始化列表的详细信息,请查看此视频。


请将以下与编程有关的内容从英语翻译为中文。如果这是预期的结果,请标记为答案。 - dj1986
int i {0}; 这段代码本身与初始化列表无关。另外,“如果这是答案,请将其标记为答案”与答案无关,不应包含在内。除此之外,关于类型转换的观点很好! - George
感谢@George的建议。关于{},它是一种新的通用初始化方式。建议始终使用,但要小心,在某些特殊情况下会产生副作用。也许你正在将其与std::initializer_list进行比较。这两者是不同的。但它们之间有一种非常有趣的关系。我在链接的视频中进行了解释。 - dj1986
我指的是 int i {0}; //Initializer list way,它可能应该是 int i {0}; // Uniform initialization。我知道这门语言很令人困惑,但初始化列表是一些不同的东西,它们本身又不同于列表初始化。请参见 cppref,C++中的初始化真是太疯狂了。 - George

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接