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

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

通常我用这个来避免复制成本:

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

C++11中的STL容器都支持移动语义吗?

如果是这样,下面的代码是否与const &具有相同的性能?

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

移动语义不仅仅神奇地让你的代码更快。

有了它们,调用像 void bar(string s) 这样的函数比必须复制参数更快,但仅在参数可以移动的情况下。考虑这种情况:

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);
   }
}

askOnce的情况下,可以将参数复制到函数中或移动。调用提示时,参数可以移动

然而,在 askManyTimes 中,您需要保持争论,这样您就无法移动,因此您实际上最终不得不无缘无故地创建 10 个问题副本。

一般来说,如果您不需要修改您的字符串或将其复制到其他地方,您仍然应该使用const std::string&;如果您以后需要复制,您可以将参考关闭。

Are STL containers in C++11 all support move semantics?

是的。

If so, does following code have the same performance as const &?

否,如果参数是 左值。如果参数是 rvalue,则性能至少 一样好。

  • lvalue 的情况下,参数 被复制。没有办法解决这个问题。函数签名指定它不修改其参数,但移动操作可能会修改正在移动的对象。

  • rvalue 的情况下,如果支持,可以移动参数。

因此,如果无论如何都要在函数内部复制参数,最好按值传递,这样右值可以移出,而左值仍将被复制。

这取决于您传入的内容。如果您传递一个临时对象,它将被 moved 传入,但如果您传递一个命名变量,它将被 copied.

bar(func_returns_string()); // move

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

您可以使用 std::move:

强制它 移动 命名变量
bar(std::move(s)); // move (now s is empty)