Dfr
Dfr

Reputation: 4185

C++11 unable to move class with unordered_map inside

In this example problematic line is declaration of repo member of Basket

#include <vector>
#include <string>
#include <memory>
#include <unordered_map>

struct Product {
    std::unique_ptr<std::string> description;
};

struct Basket {
    // this line is OK, just moves it
    std::vector<Product> ps;
    // Doesn't compile with this line uncommented ! Can't move map ?
    // std::unordered_map<std::string, Product> repo;
};


int main(int argc, const char *argv[]) {

    std::vector<Basket> baskets;
    Basket b1;
    baskets.push_back(std::move(b1));

    return 0;
}

When repo member declaration is uncommented, then i getting scary sheet of errors. Tested on gcc 4.7.2 and Clang 3.3 and got same error:

error: call to implicitly-deleted copy constructor of 'Product'
... lot of similar stuff ...

Upvotes: 2

Views: 611

Answers (3)

DanielKO
DanielKO

Reputation: 4527

It's an unimplemented feature in your libstdc++.

I checked my GCC 4.7.2's headers, unordered_map doesn't even have move constructor/assignment operator. They might have backported it for 4.7.3, but either way you'll have to upgrade your compiler and/or your libstdc++ to get that line to compile.

With a recent enough libstdc++ it compiles just fine: http://goo.gl/16Vnrj

Upvotes: 2

woolstar
woolstar

Reputation: 5083

You're other option is to make Basket in place:

baskets.emplace_back() ;

Then the compiler won't try to do any copy or move.

Upvotes: 0

Bryan Chen
Bryan Chen

Reputation: 46608

I am not sure why it failed to compile. The error message is saying it try to make a copy of Product, which can't be done because it contain unique_ptr, a move-only class.

However add

Basket() = default;
Basket(Basket &&other) = default;

does make it work.

live example

Upvotes: 2

Related Questions