C++ 中的右值绑定混乱

发布于 2024-12-27 05:46:25 字数 1217 浏览 3 评论 0原文

我有三个函数调用,我认为应该以相同的方式对待它们,但显然它们不是。我试图理解为什么三个之一无法编译(g++ -std=c++0x)。

// Minimal example to reproduce a compile bug I want to understand.

#include <iostream>
#include <string>

using namespace std;


void bar(const string &&x) { cout << "bar: " << x << endl; }

string returns_a_string() { return string("cow"); }

int main( int argc, char *argv[] )
{
    bar(string("horse"));     // ok
    bar(returns_a_string());  // ok
    string aardvark = "aardvark";
    bar(aardvark);            // not ok, fails to compile, error in next comment
    /*
      rvalue-min.cpp:29:22: error: cannot bind ‘std::string {aka std::basic_string<char>}’ lvalue to ‘const string&& {aka const std::basic_string<char>&&}’
      rvalue-min.cpp:10:6: error:   initializing argument 1 of ‘void barR(const string&&)’
    */
}

这个问题有点像 C++0x 右值引用 - 左值-右值绑定, 但是,如果在那里得到答案,我很抱歉,我无法将其提炼出来。

我想要的是能够使用任何类型的字符串调用我的函数 bar() 并让它正常工作。定义 void barR(const string &x) 就足够了,但我真的很想理解为什么。

非常感谢您帮助理解为什么第三次通话不同。

I have three function calls that I think should be treated (about) the same, but clearly they are not. I'm trying to understand why one of three doesn't compile (g++ -std=c++0x).

// Minimal example to reproduce a compile bug I want to understand.

#include <iostream>
#include <string>

using namespace std;


void bar(const string &&x) { cout << "bar: " << x << endl; }

string returns_a_string() { return string("cow"); }

int main( int argc, char *argv[] )
{
    bar(string("horse"));     // ok
    bar(returns_a_string());  // ok
    string aardvark = "aardvark";
    bar(aardvark);            // not ok, fails to compile, error in next comment
    /*
      rvalue-min.cpp:29:22: error: cannot bind ‘std::string {aka std::basic_string<char>}’ lvalue to ‘const string&& {aka const std::basic_string<char>&&}’
      rvalue-min.cpp:10:6: error:   initializing argument 1 of ‘void barR(const string&&)’
    */
}

This question is a bit along the lines of
C++0x rvalue references - lvalues-rvalue binding,
but, if it's answered there, my apologies, I wasn't able to distil it out.

What I want is to be able to call my function bar() with any sort of string and have it just work. It's enough to define void barR(const string &x), but I'd really like to understand why.

Thanks much for any help in understanding why the third call is different.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

剩余の解释 2025-01-03 05:46:25

右值引用参数的目的是专门检测对象何时为右值。因为如果一个对象是右值,那么函数就知道它不会被再次使用,所以它可以用它做任何它想做的事情。如果左值可以绑定到右值引用,则意味着我正在讨论的检测实际上并未发生。

如果要将左值传递给这些函数之一,则需要使用 std::move。通过 std::move 将对象传递给采用右值引用的函数就像是在说:“在这里,拿走这个对象,撕掉它的内脏,我不在乎它会发生什么”。

出于您的目的,正确的答案是将参数设置为常量引用。 r 值非常乐意绑定到 const 引用。除了移动构造函数之外,创建右值引用参数几乎从来都不是正确的做法。

The purpose of r-value reference parameters is to detect specifically when an object is an r-value. Because if an object is an r-value, then the function knows it won't be used again, so it can do whatever it wants with it. If an l-value could bind to an r-value reference, that would mean the detection I was talking about wasn't actually taking place.

If you want to pass an l-value to one of these functions, you need to use std::move. Passing an object via std::move to a function that takes an r-value reference is like saying, "here, take this object, rip it's guts out, I don't care what happens to it".

For your purposes, the correct answer is to make the parameter const reference. An r-value is perfectly happy being bound to a const reference. Except for move constructors, making r-value reference parameters is almost never the correct thing to do.

橘虞初梦 2025-01-03 05:46:25

您需要使用std::move。这工作正常:

bar(std::move(aardvark));

You need to use std::move. This works fine :

bar(std::move(aardvark));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文