我们可以使用参数的右值引用来“传递”吗?

时间:2016-10-06 08:38:05

标签: c++11 rvalue-reference

是否可以通过函数“传递”参数而不复制?

让我们举个例子:

0.36212 = (log2(0.211)-log2(0.001))*.0469

我的c ++编译器foo不足以说明这是否已经被优化掉了。

std::string check(std::string in, int &maxLen) { maxLen = std::max(maxLen, in.length()); return in; } //main: int maxCnt = 0; std::cout << check("test, ", maxCnt) << check("two tests, ", maxCnt) << check("three tests, ", maxCnt) << maxCnt; // would output: "test, two tests, three tests, 13" 的签名必须是什么样的,以便临时论证永远不会被复制?

我的第一个猜测是:

check(...)

如果这是正确的,那么实现会是什么样的?

说明:

  • std::string && check(std::string &&in, int &maxLen) 是一个占位符,它应该适用于任何复杂类型
  • 请提示我任何重复的问题

1 个答案:

答案 0 :(得分:0)

如果要避免输入字符串的任何副本,则应将函数编写为:

std::string const& check(std::string const& input, int& maxLen) {
    maxLen = std::max(maxLen, input.size());
    return in;
}

const引用传递的参数非常明显。为什么回归呢?因为RVO不能在这里删除副本。当您在函数中构建对象(左值)并返回它时(包括左值参数),会发生RVO。编译器通过自动构建应该去的对象来省略副本。在这里,如果您返回左值(std::string conststd::string),编译器将看到您希望将返回值存储在某处,并且必须从您对该目标的引用执行复制。通过使用std::string const&,您将避免这种情况,因为来自operator <<的{​​{1}}也会处理const引用。

总结一下,使用上面的std::basic_ostream定义:

check()

最后一次通话中的重载决议将选择:

int max(0);
std::string toto("Toto");
std::string lvalue = check(toto, max); // copy
std::string const& const_ref = check(toto, max); // no-copy
std::cout << check(toto, max) << std::endl; // no-copy
相关问题