Abhijit
Abhijit

Reputation: 63777

Why do we need a move constructor for vector of unique_ptr?

It seems that VC11 Update 2, requires a Move Constructor when pushing unique_ptr's in an std::vector. Is this a documented behavior or a known Bug?

#include < iostream>
#include <memory>
#include <vector>
struct TEST
{
    std::unique_ptr<int> m_l;
    TEST(
        std::unique_ptr<int>&& l)
    {
        m_l = std::move(l);
    };
    //Move Contructor for Test
    TEST(TEST&& o)
    {
        m_l = std::move(o.m_l);
    }
};
void Bar()
{
    std::vector<TEST> vec;
    std::unique_ptr<int> a(new int);
    //Compiles fine without a Move Constructor
    TEST(std::move(a));
    //Requires a Move Contructor to compile
    vec.push_back(
        TEST(std::move(a)));
}
int main()
{       
    Bar();
    return 0;
} 

Note

I tried the above code sans the Move Constructor on IDEONE C++11 and it compiles fine.

Upvotes: 1

Views: 423

Answers (1)

Simple
Simple

Reputation: 14410

You shouldn't have to write the move constructor yourself; it should be automatically generated by the compiler in this case. However, VC11 doesn't implement this functionality and IIRC isn't going to be added until VS2013.

Note that VC11 is complaining because the presence of a std::unique_ptr data member causes your copy constructor to be deleted. §12.8p11 describes this process of deleting a class's copy constructor:

An implicitly-declared copy/move constructor is an inline public member of its class. A defaulted copy/move constructor for a class X is defined as deleted (8.4.3) if X has:

[...]

a non-static data member of class type M (or array thereof) that cannot be copied/moved because overload resolution (13.3), as applied to M’s corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,

[...]

Upvotes: 3

Related Questions