Why does this compile in VS 2017?
#include <memory>
#include <iostream>
using namespace std;
struct x
{
x() { cout << "x()" << endl; }
~x() { cout << "~x()" << endl; }
};
template <typename T>
void foo(T&& item)
{
struct boo
{
T item;
boo(T&& t)
: item(std::move(t))
{ }
};
new boo(std::move(item));
}
int main()
{
std::unique_ptr<x> b(new x);
foo(b); // I would expect that I should put std::move(b) here.
}
With the code as written, the output is
x()
~x()
If the foo(b)
line were written as foo(std::move(b))
, then the output is simply
x()
ie the instance of x
is leaked. I would expect the code as written to be a compiler error, since it seems like the unique_ptr<x>
is copied at the call to foo
?
When clang is used it doesn't compile: https://wandbox.org/permlink/HCIDXxS1yqyq7uCb And it works with Visual Studio: http://rextester.com/GUR47187
So it looks like a bug in VS.
It always works with move
: https://wandbox.org/permlink/u3N06Idr8ELo9SIp
Also in case of templates std::forward
should be used instead std::move
.
Here is code which finds how VS resolves templates:
void __cdecl foo<classstd::unique_ptr<struct x,struct std::default_delete<struct x> >&>(class std::unique_ptr<struct x,struct std::default_delete<struct x> > &)
So unique_ptr
is not moved just passed by reference to unique_ptr
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.