C++中的右值绑定混淆
rvalue binding confusion in C++
我有三个函数调用,我认为应该一视同仁,但显然不是。我试图理解为什么三个中有一个不编译(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)
已经足够了,但我真的很想了解原因。
非常感谢您帮助我们理解为什么第三个电话不同。
r值引用参数的目的是专门检测对象何时为r值。因为如果一个对象是r值,那么函数知道它不会再被使用,所以它可以对它做任何它想做的事情。如果l值可以绑定到r值引用,那就意味着我所说的检测实际上并没有发生。
如果要将l值传递给其中一个函数,则需要使用std::move
。通过std::move
将一个对象传递给一个接受r值引用的函数,就像在说,"在这里,拿走这个对象,把它的内脏挖出来,我不在乎它会发生什么"。
出于您的目的,正确的答案是使参数const引用。r值被绑定到const引用是非常愉快的。除了move构造函数,生成r值引用参数几乎从来都不是正确的做法。
您需要使用std::move
。这很好:
bar(std::move(aardvark));
相关文章:
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 在基于范围的for循环中使用结构化绑定声明
- 使用 LuaBridge 将 LuaJIT 绑定到C++会导致"PANIC: unprotected error"
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- 在使用GPU支持编译Tensorflow时,会遇到CUDA_TOOLKIT_PATH未绑定变量
- 视觉studo 2019中的漫画和静态/动态绑定
- 将自由函数绑定为类成员函数
- 将常量指针引用绑定到非常量指针
- 在派生类中绑定非静态模板化成员函数
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 在 openGL 中多次绑定缓冲区
- 定义有趣的宏和正则表达式在Z3 C++绑定
- 使用结构化绑定'Reflection'
- 为什么 std::绑定错误参数可以成功?
- 如何绑定 C++ gRPC 客户端的网络接口
- 在 openmp 中,omp_get_thread_num是否绑定到物理线程?
- C++绑定(已弃用)
- 运行时错误:引用绑定到类型为"int"的空指针
- 有没有办法将重载的类函数绑定到函数对象?
- 替换 C++17 中移除的绑定 1st