简体   繁体   中英

unique_ptr as a template parameter

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM