对于常规局部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());
答案 0 :(得分:-1)
让我们抛开std::move()
并创建此函数:
struct sometype {};
const sometype &foobar( const sometype &cref ) { return cref; }
现在我们使用它:
const sometype &ref = foobar( sometype() );
您如何看待,在这种情况下会延长临时寿命吗?不,它不会。仅当您直接分配引用时,才可以延长寿命。当它通过一个函数或通过static_cast
或std::move
时,延长就消失了。因此,您在std::move()
struct sometype {
sometype() { std::cout << "ctype()" << std::endl; }
~sometype() { std::cout << "~ctype()" << std::endl; }
};
const sometype &foobar( const sometype &cref ) { return cref; }
int main()
{
const sometype &cref1 = foobar( sometype() );
sometype &&cref2 = std::move( sometype() );
std::cout << "main continues" << std::endl;
}
输出:
ctype()
~ctype()
ctype()
~ctype()
main continues
注意:您不应该在return语句上使用std::move()
,它不会给您任何东西。
更改代码。您应该记住std::move()
不会移动任何东西。这是由特殊的赋值运算符或构造函数(如果为类型提供的)完成的。因此,当您编写此代码时:
const type &ref = std::move( something );
没有构造函数或赋值运算符,因此没有移动。为了使实际动作发生,您必须将其分配给变量:
type val = std::move( something );
如果可能的话,现在将搬家,否则将复制。