С++: Можно ли использовать ссылку в качестве значения на карте?

Можно ли использовать ссылку в качестве значения в стандартном контейнере карты в С++?
Если нет - почему бы и нет?

Пример объявления:

map<int, SomeStruct&> map_num_to_struct;

Пример использования:

...
SomeStruct* some_struct = new SomeStruct();
map_num_to_struct[3] = *some_struct;
map_num_to_struct[3].some_field = 14.3;
cout<<some_struct.some_field;
...

Я ожидаю увидеть распечатку 14.3...

Ответ 1

Нет. Типы значений контейнера STL должны быть присваиваемыми. Ссылки не могут быть назначены. (Вы не можете назначить им другой объект для ссылки.)

Ответ 2

Нет, нет. Однако вы можете использовать указатели как тип значения.

Ответ 3

Я так не думаю, что ссылки должны рассматриваться как постоянные указатели на определенный элемент, если я правильно помню. Но вы могли бы просто использовать указатели для того же эффекта.

Ответ 4

Нет, вы не можете использовать ссылки, но можете использовать указатели. Кажется, вы смешиваете оба в своем примере. Попробуйте:

map<int, SomeStruct *> map_num_to_struct;
SomeStruct* some_struct = new SomeStruct();
map_num_to_struct[3] = some_struct;
map_num_to_struct[3]->some_field = 14.3;
cout<<some_struct->some_field;

Ответ 5

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

В любом случае вы можете использовать tr1 reference_wrapper.

Ответ 6

Я считаю, что это возможно, с ограничениями. Поскольку ссылки не могут быть назначены на более позднем этапе, вы не сможете вызвать operator [] на карте. Однако вы можете вызывать различные другие функции-члены. Пока вы не нарушаете никаких правил для ссылок. Например:

// You need the instances to exist before
auto a1 = SomeStruct();
auto a2 = SomeStruct();
auto a3 = SomeStruct();

// Creating the map with an initializer list.
std::map<int, SomeStruct&> map_num_to_struct = {
    { 1, a1 },
    { 2, a2 },
    { 5, a3 }
};

// The following won't work because operator[] returns
// a reference to the value, which can't be re-assigned.
// map_num_to_struct[6] = a1;

// These will work.
map_num_to_struct.insert({6, a1});
map_num_to_struct.insert(std::pair<int, SomeStruct&>(7, a1));

// Iterating through the map.
for (auto &a: map_num_to_struct) {
    cout << a.first << ": " << a.second.some_field << endl;
}

// We can't use operator[] for indexing.
// map_num_to_struct[5].do_something();
auto a_iter = map_num_to_struct.find(5);
if (a_iter != map_num_to_struct.end()) {
    cout << a_iter->first << ": " << a_iter->second.some_field << endl;
    a_iter->second.some_field = 14.3;
    cout << a_iter->first << ": " << a_iter->second.some_field << endl;
}

Я не знаю, сделали ли это новые стандарты C++, но это работает, по крайней мере, с GCC и clang.