2016-01-14 42 views
10

我整天阅读关于传递参数的最有效方式,我很困惑。我想通过一个载体是这样的:C++ 11传递给构造函数的向量

Foo f({1,2,3}); 

我只是想初始化我_member变量与传递的载体。现在的问题是应该怎么我的构造看:

// pass by value 
Foo (vector<int> vec) : _member{vec} {} 

// const reference 
Foo (const vector<int>& vec) : _member{vec} {} 

// rvalue reference 
Foo (vector<int>&& vec) : _member{std::move(vec)} {} 
+2

你的传递值应该有一个“std :: move” – CoffeeandCode

+0

将新矢量初始化为矢量并通过它 –

回答

10

最简单的方法是按值取载体,并将其移动:

Foo (vector<int> vec) : _member{std::move(vec)} {} 

相较于一对const vector<int>&/vector<int>&&重载,你最多支付一次额外的移动(这对于向量来说非常便宜),但不必编写两个构造函数(如果有多个参数,它可能会很快爆炸)。

+0

你是什么意思“额外”的举动?相比之下呢? – SergeyA

+0

谢谢@ T.C。还有一个问题:什么时候应该使用?只有当我们传递大量载体或者所有时间?我的意思是像例子中的小矢量什么是标准方式? – Petrof

+0

@Petrof这对小型和大型矢量同样适用。 –

0

在这种特殊情况下,您传递的是rvalue,所以第三选择是最好的。

+0

因为一个来电者代表每个来电者? – ildjarn

+0

当然不是,但是因为他提供了一个特定的例子,所以我相信这个例子特定的最佳选项也很好。 – ViNi89

2

传值是时下流行的很多圈子。我认为这是一个很好的选择,因为各种原因,所以我同意T.C.的答案。然而,传递参数的最佳方式(非构造函数)的更广泛问题,我很少推荐按值传递。我真的非常强烈地建议您听一听Herb Sutter的话题:https://youtu.be/xnqTKD8uD64?t=51m34s。总而言之,在构造函数之外:通过值传递给const-ref的简单传递提供了更差的最坏情况性能保证,它在所有情况下都比const-ref/rvalue-ref重载性能更差,它使得它更难以提供异常保证,它切片多态类型,复制时有条件时不能使用。

在大多数情况下,您或者不关心理性的表现,或者您关心很多。在第一种情况下,使用const-ref更简单和容易。在第二种情况下,按价值传递不够好。同样,请记住,由于几个不同的原因,构造函数是不同的(他们正在构建的东西而不是移动分配,他们需要很多参数,这会强烈影响您需要的重载次数)。

不幸的是,这个问题并没有这么简单的答案。最终,两种方法都足够好,但我认为要掌握C++,你想知道两者的优点和缺点。

+0

谢谢你的回答。我认为我理解基于这个[链接]的非构造函数(http://stackoverflow.com/questions/32810939/c-lvalues-rvalues-references-parameters-and-performance)我的问题是与构造函数和T.C.答案帮助我了解了很多。我会确定检查该视频,谢谢。 – Petrof

+0

“*通过值传递给更糟糕的最坏情况的性能保证相比,简单通过const-ref *”除非你需要一个副本,萨特说完全一样的东西。 “*在所有情况下,它的性能比const-ref/rvalue-ref重载性能差*”在许多情况下,只需花费一次移动的代价,但总是花费代码的两倍。 “*它使得更难以提供异常保证*”实际上,它使得它们更容易,因为负担转移给了调用者。 “*它切片多态类型*”完全正交的问题。 “*拷贝有条件时不能使用*”见第一点。 – ildjarn

+0

条件性和多态性只是额外的特例,因此它们使事情变得更加复杂。通常情况下,性能并不重要,当性能不重要时,const ref应该成为默认值。至于表现,那*不是*萨特所说的。 Sutter比较复制构造(传值)和复制赋值(pass-by-const-ref);并指出在常见类型(矢量/字符串)复制分配的许多实际用例中,*明显更便宜。换句话说:如果我们忽略了perf,那么按值传递显然更糟糕,而且对于perf也不是很好。 –