Ошибка памяти из-за итератора std::map в классе, производном от std::map

Я получаю класс из 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 &'

Что это std::make_unique<ValueType>(value) предполагает делать?

Slava 07.06.2019 10:52

Не ваша проблема, но стоит прочитать: Есть ли реальный риск извлечения из контейнеров C++ STL?

Yksisarvinen 07.06.2019 10:54

Предполагается, что он возвращает unique_ptr, указывающий на значение типа Value, найденное итератором.

Ninrich 07.06.2019 10:54

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

L. F. 07.06.2019 10:55

Тогда вы совершенно на ложном пути. 1 - std::make_unique создает новый экземпляр. 2 - std::unique_ptr обеспечивает право собственности. 3 - вы пытаетесь создать новый экземпляр и инициализировать его с помощью итератора

Slava 07.06.2019 10:56

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

Ninrich 07.06.2019 10:57

Вы пытаетесь вызвать конструктор ValueType, передавая в качестве аргумента один объект типа std::map<KeyType, ValueType>::iterator. Я полагаю, вы имели в виду std::make_unique<ValueType>(*value);, но все еще очень неясно, что вы пытаетесь сделать с владением объектами здесь (почему бы, например, не вернуть просто ValueType?)

Yksisarvinen 07.06.2019 11:01

стандартные контейнеры на самом деле не предназначены для публичного наследования. для начала у них нет виртуального деструктора

463035818_is_not_a_number 07.06.2019 11:01

Я возвращаю unique_ptr, потому что это была моя задача. Как сделать так, чтобы вызывающий mySelect() стал владельцем возвращаемого объекта?

Ninrich 07.06.2019 11:04
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
9
117
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Прежде всего этот код:

 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 больше не сможет владеть этим объектом.

Другие вопросы по теме