简体   繁体   English

我们有移动语义,不需要使用const&作为STL容器参数吗?

[英]No need to use const & for STL container parameters as we have move semantics?

Usually I use this to avoid copying cost: 通常我用它来避免复制成本:

void bar(const string& s);
void foo(const vector<int>& v);

Are STL containers in C++11 all support move semantics? C ++ 11中的STL容器是否都支持移动语义?

If so, does following code have the same performance as const & ? 如果是这样,以下代码是否具有与const &相同的性能?

void bar(string s);
void foo(vector<int> v);

Move semantics don't just magically make your code faster. 移动语义不只是神奇地使你的代码更快。

With them, calling a function like void bar(string s) is faster than it would be if you had to copy your arguments, but only in the case where the argument can be moved. 使用它们,调用像void bar(string s)这样的函数比你必须复制参数时更快,但仅限于可以移动参数的情况。 Consider this case: 考虑这种情况:

std::string prompt(std::string prompt_text);

void askOnce(std::string question) { prompt(question); }

void askManyTimes(std::string question) {
   for(int i=0; i<10; ++i) {
       askOnce(question);
   }
}

In the case of askOnce , the argument can be copied into the function or moved. askOnce的情况下,可以将参数复制到函数中或移动。 When it's calling prompt, the argument can be moved. 当它调用prompt时,可以移动参数。

In askManyTimes however, you need to keep the argument around so you can't move, so you actually end up having to create 10 copies of your question for no good reason. 然而,在askManyTimes中,你需要保持参数,以便你不能移动,所以你实际上最终必须创建10个问题的副本,没有充分的理由。

Generally, if you don't need to modify your string or copy it somewhere else, you should still use const std::string& ; 通常,如果您不需要修改字符串或将其复制到其他地方,您仍应使用const std::string& ; You can leave the reference off if you need to do a copy later on anyway. 如果您以后需要进行复制,可以将参考文件保留为关闭状态。

Are STL containers in C++11 all support move semantics? C ++ 11中的STL容器是否都支持移动语义?

Yes. 是。

If so, does following code have the same performance as const & ? 如果是这样,以下代码是否具有与const &相同的性能?

No, if the argument is an lvalue . 不,如果参数是左值 If the argument is an rvalue , the performance is at least as good. 如果参数是右值 ,则性能至少同样好。

  • In the case of an lvalue , the argument has to be copied. 左值的情况下,参数必须被复制。 There's no way around that. 没有办法解决这个问题。 The function signature specifies that it doesn't modify its arguments, but a move operation might modify the object that is being moved from. 函数签名指定它不修改其参数,但移动操作可能会修改正在移动的对象。

  • In the case of an rvalue , the argument can be moved from, if supported. rvalue的情况下,如果支持,则可以移动参数。

So if the parameter will be copied inside the function anyway, it is better to pass it by value, so that rvalues can be moved from, while lvalues will still be copied. 因此,如果参数将被复制到函数内部,最好通过值传递,以便可以移动rvalues,同时仍然可以复制lvalues。

It depends what you pass in. If you pass a temporary object it will get moved in but if you pass a named variable it will get copied . 这取决于你传入的内容。如果你传递一个临时对象,它将被移入 ,但如果你传递一个命名变量,它将被复制

bar(func_returns_string()); // move

std::string s;
bar(s); // copy

You can force it to move a named variable using std::move : 您可以使用std::move强制它移动命名变量:

bar(std::move(s)); // move (now s is empty)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM