简体   繁体   中英

Error Constructing std::map<T, unique_ptr<S>> from an initializer_list

C2280 - Attempting to reference a deleted function is the error I am getting when I attempt to construct an std::map> from an initializer_list

I've made the simplest possible code(below) representing my problem:

#include <string>
#include <map>
#include <memory>
using namespace std;

int main() {
    map<string, unique_ptr<int>> MyMap{
        { "first" ,make_unique<int>(6)  },
        { "second",make_unique<int>(22) },
        { "third" ,make_unique<int>(86) }
    };
}

So I realize that unique_ptr cannot be copied, but since make_unique is returning an rvalue, shouldn't the unique_ptr being moved into the initializer_list? By the way, if I replace unique_ptr with shared_ptr then the problem is solved, but is not the solution I am looking for, I would like to retain that initialization style and the unique_ptr. So at which point this problematic call to a deleted function is happening exactly? There is a way to have it compile without replacing the unique_ptr?

Sadly, this is one of the limitations of std::initializer_list objects. They only offer const access to their elements, so it is not possible to move out of them. Your best bet is to initialize your map the old-fashioned way.

map<string, unique_ptr<int>> MyMap;
MyMap["first"] = make_unique<int>(6);
// etc.

If you need the map to be const , you can create a temporary map and move from that:

const map<string, unique_ptr<int>> myMap = [] {
    map<string, unique_ptr<int>> m;
    m["first"] = make_unique<int>(6);
    // etc.
    return m;  // RVO or implicit move
}();

You could also use the range constructor of std::map , but then you'd have to write a special iterator type for this yourself, which would be annoying.

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