非 Const 左值引用
Posted
技术标签:
【中文标题】非 Const 左值引用【英文标题】:Nonconst lvalue reference 【发布时间】:2020-04-06 18:19:16 【问题描述】:我正在创建一个无向图,每次我将邻居 A 添加到节点 B 时,我都必须将节点 B 添加为 A 的邻居,但我的方法不起作用。
Non-const lvalue reference to type 'Element *' cannot bind to a temporary of type 'Element *'
class Element
std::vector<Element *> m_neighbours;
private:
public:
void addNeighbour(Element*& neighbour)
m_neighbours.push_back(neighbour);
neighbour->addNeighbour(this);
;
-
发生了什么?
最好的解决方法?
【问题讨论】:
emplace_back
指针而不是 push_back
的动机是什么?
通过引用传递指针对我来说似乎也是一种代码味道,尤其是因为它在函数内没有改变。
我改了
但是如果我在理论上不通过引用传递它,我有一个副本,所以在调用 addNeighbour 时我不会调用真正的邻居不是吗?
@HectorEstebanCabezos 您将拥有指针的副本,而不是被指向的东西的副本。
【参考方案1】:
要了解问题所在,让我们假设您编写了以下代码:
void addNeighbour(Element*& neighbour)
m_neighbours.emplace_back(neighbour);
neighbour->addNeighbour(this);
neighbour = nullptr; // <--- This is new
现在,想想当你拨打这个电话时会发生什么:
neighbour->addNeighbour(this);
对函数的调用通过引用传入this
,意思是“请随时重新分配this
”。然后在函数调用中,最后一行确实尝试将neighbour
重新分配给nullptr
。但这是个问题,因为你不会写
this = nullptr; // Error!
因为this
是一个右值。
这里最简单的解决方法是不通过引用获取参数,因为在实际需要引用的地方你没有对它做任何事情。只需接收Element*
,并说“请给我一份你感兴趣的指针的副本。”
(独立 - 你的代码会给你带来麻烦,因为调用 A->addNeighbour(B)
将调用 B->addNeighbour(A)
,它调用 A->addNeighbour(B)
,它调用 B->addNeighbour(A)
,等等,直到你炸毁你的调用堆栈。你应该添加一个在此处检查以确保,如果 Element
已被记录,则不要再次添加它。为此,您可能希望将 m_neighbours
设为 std::unordered_set
而不是 std::vector
。)
【讨论】:
当您尝试更改函数内部指针指向的内容时,您可能会引用它。尽管您也希望有充分的理由不只是使用退货。【参考方案2】:this
指针 is defined to be a prvalue,而您的函数采用 lvalue
。该语言禁止这种绑定for various reasons。您没有修改给定的指针,因此只需按值而不是按引用传递它。
void addNeighbour(Element* neighbour);
而不是
void addNeighbour(Element*& neighbour);
【讨论】:
以上是关于非 Const 左值引用的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 11 中将非 const 左值引用绑定到右值是不是有效?(修改)
为啥我不能将 const 左值引用绑定到返回 T&& 的函数?