Я получаю класс из std::map, так как хочу создать свои собственные методы для этой структуры данных. У меня проблемы с "mySelect", который должен возвращать nullptr, если элемента нет, и unique_ptr в противном случае.
Я пытался указать ключевое слово typename перед объявлением итератора, но безрезультатно.
template <class KeyType, class ValueType>
class Container : public std::map<KeyType, ValueType> {
public:
std::unique_ptr<ValueType> mySelect(KeyType key) {
typename map<KeyType, ValueType>::iterator value;
if ((value = this->find(key)) == this->end())
return nullptr;
return std::make_unique<ValueType>(value);
}
}
Я получаю эту ошибку:
Error C2664 'std::vector<std::shared_ptr<Transaction>,std::allocator<_Ty>>::vector(const std::vector<_Ty,std::allocator<_Ty>> &)': cannot convert argument 1 from 'std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>' to 'const _Alloc &'
Не ваша проблема, но стоит прочитать: Есть ли реальный риск извлечения из контейнеров C++ STL?
Предполагается, что он возвращает unique_ptr, указывающий на значение типа Value, найденное итератором.
Можете ли вы предоставить минимальный воспроизводимый пример? Покажите, как используется ваш Container.
Тогда вы совершенно на ложном пути. 1 - std::make_unique создает новый экземпляр. 2 - std::unique_ptr обеспечивает право собственности. 3 - вы пытаетесь создать новый экземпляр и инициализировать его с помощью итератора
Код ломается до того, как его можно использовать. Я считаю, что этот класс должен компилироваться сам по себе.
Вы пытаетесь вызвать конструктор ValueType, передавая в качестве аргумента один объект типа std::map<KeyType, ValueType>::iterator. Я полагаю, вы имели в виду std::make_unique<ValueType>(*value);, но все еще очень неясно, что вы пытаетесь сделать с владением объектами здесь (почему бы, например, не вернуть просто ValueType?)
стандартные контейнеры на самом деле не предназначены для публичного наследования. для начала у них нет виртуального деструктора
Я возвращаю unique_ptr, потому что это была моя задача. Как сделать так, чтобы вызывающий mySelect() стал владельцем возвращаемого объекта?





Прежде всего этот код:
return std::make_unique<ValueType>(value);
логически равно этому:
std::unique_ptr<ValueType> tmp = new Value(value);
return tmp;
(это не то же самое, поэтому вы не должны заменять одно другим, просто чтобы вы поняли). Итак, вы пытаетесь создать новый экземпляр класса Value и инициализировать его из итератора. Это не сработает, если Value не предоставит такой конструктор. Если вы хотите сделать копию и вернуть ее с передачей права собственности, измените свой код на:
return std::make_unique<ValueType>(value->second);
но я не уверен, что это то, что вы хотите сделать. Если вы хотите вернуть указатель на существующий объект, вы не можете использовать здесь std::unique_ptr, поскольку он обеспечивает уникальное владение (отсюда и название), вам нужно либо сохранить std::shared_ptr на карте вместо объекта по значению и вернуть его копию, либо просто вернуть необработанный указатель.
How is it possible to make the caller of mySelect() to become the owner of the returned object?
Либо, как я сказал, вы сохраняете объект с помощью std::shared_ptr и разделяете право собственности с вызывающей стороной этого метода, либо вы изначально сохраняете объект как std::unique_ptr, но затем вам нужно его переместить, так как ваш std::map больше не сможет владеть этим объектом.
Что это
std::make_unique<ValueType>(value)предполагает делать?