为啥非 const 引用必须用左值初始化?

Posted

技术标签:

【中文标题】为啥非 const 引用必须用左值初始化?【英文标题】:Why must a non-const reference be initialized with an lvalue?为什么非 const 引用必须用左值初始化? 【发布时间】:2018-08-14 04:04:42 【问题描述】:

这是一段导致 C2664 错误的 sn-p 代码:

无法将参数 1 从 'std::unique_ptr>' 转换为 'ComPtr &'

那么为什么非 const 引用必须用左值初始化呢?除了声明一个新变量,如何避免这种情况?

#include <memory>
#include <list>

class Component 
;

using ComPtr = unique_ptr<Component>;
using ComList = list<ComPtr>;
ComList coms;

void addComponent(ComPtr&c) 
    coms.push_back(c);


int main() 
    addComponent(make_unique<Component>()); //Error here.
    return 0;

【问题讨论】:

@PaulRooney “编译器允许我们对临时文件进行更改不是一个好主意吗?”这正是 r-value 引用可以让你做的事情。 How come a non-const reference cannot bind to a temporary object?的可能重复 【参考方案1】:

这样你就不必做你正在与之抗争的事情的写法是:https://godbolt.org/g/vceL4q

#include <memory>
#include <list>
using namespace std;

class Component 
;

using ComPtr = unique_ptr<Component>;
using ComList = list<ComPtr>;
ComList coms;

void addComponent(ComPtr c)  // <== change here
    coms.push_back(std::move(c)); // and here


int main() 
    addComponent(make_unique<Component>());
    return 0;

addComponent 中的c 将通过移动构造函数创建,因为 make_unique 的结果是一个右值。

最好以这种方式按值传递大型(移动友好)数据结构。

【讨论】:

以上是关于为啥非 const 引用必须用左值初始化?的主要内容,如果未能解决你的问题,请参考以下文章

c++产生非常量引用的初始值必须是左值

为啥不能使用右值来初始化左值引用?

为啥我不能将 const 左值引用绑定到返回 T&& 的函数?

为啥在特殊成员函数中将 r 值绑定到 const 左值引用是非法的?

为啥我需要将默认引用参数定义为 const 以便我可以为其分配左值? [复制]

“非常量引用的初始值必须为左值“及“匿名对象“