C++11 和广义初始化器惯例

4

C++11引入了新的通用初始化方式,这可能会很好用。问题是:旧语法中的任何一种初始化对象的方式是否被认为已经过时了。在C++03中,一个对象可以被初始化为:

  1. Foo bar(x)
  2. Foo bar=Foo(x)

选项(1)更受欢迎,因为它不涉及复制。在C++11中还有更多的方法:

  1. Foo bar{x}
  2. auto bar=Foo{x}

有了移动构造函数和赋值运算符,选项(4)也应该没问题了。是(1)被认为已过时,而推荐使用(3)或(4)吗?

此外,在C++03中,规则是所有只接受一个参数的构造函数都应该是显式的(除了拷贝构造函数)。其他构造函数总是显式的。使用通用初始化方式后,任何构造函数都可以是隐式的。新规则是到处都放显式吗,还是只在转换会导致副作用(分配大量内存、创建文件等)或丢失信息(double到float)时才放显式?


1
我认为你有几个好问题,但是你真的应该限制自己每个“问题”只提一个问题。 :) - erip
也许是的,但这一切都与初始化有关。 - user877329
2
我认为更合适的第二种写法应该是 Foo bar = x(这样就和第一种写法完全一致了)。为什么要显式地创建一个临时对象,然后再调用复制构造函数呢? - luk32
@user877329:您可以从SO上现有的问题列表中看到,我们不会将所有关于一个主题的问题捆绑成一个问题。 :) - Lightness Races in Orbit
1
@luk32 @user877329 对于显式构造函数,推荐使用单参数构造函数,因此Foo bar = x将无法编译。不管怎样,在选项(2)和(4)中的复制或移动通常会被省略,所以不用担心。 - Brandlingo
显示剩余5条评论
1个回答

3

在 (3) 或 (4) 的情况下,(1) 被认为已过时了吗?

“已过时”可能不是最好的选择。尽可能使用花括号初始化更好。我之所以提到这一点,是因为 Foo(x) 并不总是对应于 Foo{x}

考虑 std::vector 的构造函数:

std::vector<int> v1(10, 0); // Creates a vector of size 10 initialized with all 0's.
std::vector<int> v2{10, 0}; // Creates a vector with elements {10, 0}.

构造函数的行为有所不同;因此,不能说应该放弃(1)而选择(3)或(4)。

这个例子有点回答了你的第二个问题:

那么新规则是到处都要放置 explicit 吗?

是的。因为可能存在歧义,你不希望编译器尝试解决它 - 将其标记为 explicit


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