Вставка элемента в карту без оператора присваивания
Не получается сделать карту, которая по номеру id возвращает экземпляр моего класса. Вот код:
struct Ref {
Ref(int& x) : x{x} {}
int& x;
};
#include <map>
int main() {
int x, y, z;
std::map<int, Ref> ref_by_id;
ref_by_id[0] = Ref{x};
ref_by_id[1] = Ref{y};
ref_by_id[2] = Ref{y};
}
Выводит ошибку:
error C2280: 'Ref &Ref::operator =(const Ref &)': attempting to reference a deleted function
Пробовал не использовать =, а вызывать конструктор ref_by_id[0]{Ref{x}};, но тоже не работает.
Ответы (3 шт):
Вы неправильно заполняете, оператор [] сначала создает элемент с конструктором по-умолчанию, а потом возвращает его. Соответственно попытка присвоить существующему элементу новое значение буден заведомо неудачной. Вместо этого следует сразу при создании элемента передавать нужную ссылку:
ref_by_id.emplace
(
::std::piecewise_construct
, ::std::forward_as_tuple(0)
, ::std::forward_as_tuple(x)
);
ссылки или классы содержащие ссылки не могут быть содержимым стандартных контейнеров, так как для них не определен оператор присваивания, потому что ссылка должна быть инициализирована во время создания, поэтому я бы посоветовал смотреть в сторону указателей
возможная реализация:
#include <iostream>
#include <map>
#include <memory>
struct Ref {
Ref() = default;
Ref(std::shared_ptr<int>& ptr) : ptr(ptr) {}
std::shared_ptr<int> ptr;
};
int main() {
std::shared_ptr<int> x = std::make_shared<int>(5);
std::shared_ptr<int> y = std::make_shared<int>(10);
std::shared_ptr<int> z = std::make_shared<int>(15);
std::map<int, Ref> ref_by_id;
ref_by_id.insert({ 0, x });
ref_by_id.insert({ 1, y });
ref_by_id.insert({ 2, z });
std::cout << *ref_by_id[0].ptr << '\n';
std::cout << *ref_by_id[1].ptr << '\n';
std::cout << *ref_by_id[2].ptr << '\n';
return 0;
}
Вы сейчас создаете временное значение, затем сохраняете ссылку на него, затем временное значение удаляется, а ссылка остается. Оно вообще не может работать правильно. Вам нужно либо корректно определить конструкторы, либо использовать std::reference_wrapper.
Или
int value= 2;
std::tuple<int&> ref = std::tie(value)