【发布时间】:2018-10-03 19:27:58
【问题描述】:
对于常规的本地 const 引用变量,范围是 prolonged。这就是以下代码按预期工作的原因:
#include <iostream>
#include <memory>
struct foo
{
foo()
{
std::cout << "foo() @" << (void*)this << std::endl;
}
~foo()
{
std::cout << "~foo() @" << (void*)this << std::endl;
}
};
int main()
{
auto const& f = std::make_shared<foo>();
std::cout << "f = " << f.get() << std::endl;
return 0;
}
// prints:
// foo() @0x55f249c58e80
// f = 0x55f249c58e80
// ~foo() @0x55f249c58e80
使用std::move() 分配移动的对象时,这似乎无法按预期工作:
#include <iostream>
#include <memory>
#include <list>
struct foo
{
foo()
{
std::cout << "foo() @" << (void*)this << std::endl;
}
~foo()
{
std::cout << "~foo() @" << (void*)this << std::endl;
}
};
int main()
{
std::list<std::shared_ptr<foo>> l;
l.push_back(std::make_shared<foo>());
auto const& f = std::move(l.front());
l.clear();
std::cout << "f = " << f.get() << std::endl;
return 0;
}
// prints
// foo() @0x564edb58fe80
// ~foo() @0x564edb58fe80
// f = 0x564edb58fe80
std::move() 确实改变了范围,还是我在处理编译器错误?
将变量从 auto const& f 更改为 auto f 可以解决问题。如果我将移动包装到另一个函数中,它也可以工作:
auto const& f = [&]() { return std::move(l.front()); }();
这几乎就像std::move() 不共享与函数调用相同的语义,而是好像它只是一个常规的变量赋值:
auto const& f = std::move(l.front());
【问题讨论】:
-
你误解了
std::move,但我不确定到底是怎么回事。std::move在您展示的任何示例中都没有效果,除了可能禁用某些优化。std::move只是从T&到T&&的转换,它将左值引用转换为右值引用。 -
“使用 std::move() 分配移动对象时”看起来有必要对某些人重复一遍又一遍:
std::move()本身不会移动任何东西 -
@FrançoisAndrieux 它确实会影响我的回答
-
我意识到它在这个特定的示例中没有任何影响。我实际上是在将一个对象从
std::list元素移动到一个本地 const 引用变量中,然后从列表中删除该条目,并期望该变量仍然有效。 -
我用我实际遇到的情况更新了我的问题中的第二个 sn-p。使用
std::move()将元素移出std::list。将auto const& f更改为auto f可以解决此问题,但同时我也希望出现相同的行为。
标签: c++ scope reference constants move