Подтвердить что ты не робот

С++ 11 инициализировать карту

Я пытаюсь инициализировать карту STL, используя синтаксис С++ 11, но это, похоже, не работает. После инициализации, когда я пытаюсь получить доступ к элементу, он пытается вызвать частный конструктор Foo. Я что-то пропустил? Он работает, если я использую его. Мне интересно, могу ли я использовать оператор [] для доступа к инициализированным значениям...

#include <map>
#include <string>

class Foo{
public:
    int a, b;
    Foo(int a_, int b_){
        a = a_;
        b = b_;
    }

private:
    Foo(){};
};


int main(){

    std::map<std::string, Foo> myMap = { {"1", Foo(10,5)}, {"2", Foo(5,10)} };
    int b  = myMap["1"].b;    // it tries to call private constructor of Foo.
    return 0;
}
4b9b3361

Ответ 1

Когда вы используете operator[] на карте, вы можете использовать оператор для получения значения с карты или назначения значения на карте. Чтобы присвоить значение на карте, карта должна построить объект своего типа значения и вернуть его по ссылке, чтобы вы могли использовать operator= для перезаписывания существующего объекта.

Следовательно, тип должен быть по умолчанию конструктивным, чтобы можно было создать новый объект для назначения.

Во время выполнения конструктор не будет вызываться, если ключ уже существует, но компилятор не знает, используете ли вы когда-либо operator[] для доступа к значению, которое не существует, поэтому оно требует конструктор должен быть общедоступным.

Ответ 2

operator[] для карты требует, чтобы тип был конструктивным по умолчанию, потому что он создает новую запись, если ее не существует.

Вместо этого вы можете использовать at(), который выдает, если запись не существует:

int b  = myMap.at("1").b;