unique_ptr<карта<int, unique_ptr>> по сравнению с unique_ptr>><карта>

#c #unique-ptr

Вопрос:

Работаю над исправлением unique_ptr, где мне нужно передать unique_ptr карты какой-либо функции в качестве аргумента.

Если мы определяем unique_ptr карту через std::make_unique , нужно ли нам также объявлять значение карты как unique_ptr тип?

Или нам не нужно этого делать, пока мы определяем unique_ptr карту в куче, тогда мы можем заполнить значения карты с помощью переменной стека, и карта может хранить копии этих переменных стека на протяжении всего срока службы в куче, пока владелец не уничтожит эту карту?

подобный этому:

 auto heap_map = std::make_unique<std::map<
  int,
  std::unique_ptr<Value>>>();
    
(*heap_map)[1] = Value(arg1, arg2);
(*heap_map)[2] = Value(arg1, arg3);
 

Или мы должны сделать это вот так:

 auto heap_map = std::make_unique<std::map<
  int,
  std::unique_ptr<Value>>>();

(*heap_map)[1] = std::make_unique<Value>(arg1, arg2);
(*heap_map)[2] = std::make_unique<Value>(arg1, arg3);
 

Пожалуйста, пролейте некоторый свет на разницу между этими двумя приведенными выше примерами использования.

Комментарии:

1. Напрашивается вопрос, почему указатель на map в первую очередь?

2. Одно unique_ptr не подразумевает и не вынуждает другое unique_ptr . Вы используете uniqiue_ptr в каждом конкретном случае, когда это имеет смысл. Единственное, что имеет значение, — это «вам нужно динамическое распределение?» и, если да, » unique_ptr Описывает ли право собственности на распределение?» Ваш вопрос не предоставляет нам достаточной информации, чтобы помочь вам принять эти решения. Я подозреваю, что вам не нужно динамическое распределение, потому что обычно в стандартном контейнере библиотеки этого нет.

3. «карта может содержать эти значения стека» — карта никогда не содержит того, что вы называете «значениями стека». Скорее, он содержит их копии, хранящиеся там, где карта решит, что они должны храниться.

4. Пожалуйста, объясните, почему map<int, Value> это не единственное, что вы используете. Является Value ли частью иерархии наследования с virtual функциями? Самое внешнее unique_ptr , вероятно, просто добавляет шум в ваш код.

Ответ №1:

Независимо от того, есть ли у вас карта или std::unique_ptr для карты. Реальная проблема здесь заключается в том, как заполнить записи unique_ptr на карте.

 // create the unique_ptr
auto ptr = std::make_unique<Value>(arg1,arg2);

// use the insert function instead of[]
// and unique pointers need to be moved (which will reset ptr)
// so do not use that after this call
heap_map->insert({0,std::move(ptr)});