Как создать карту из initializer_list с некопируемыми членами в C ++? - PullRequest
2 голосов
/ 05 августа 2020

Итак, у меня есть карта, на которой хранятся объекты класса с удаленным конструктором копирования, поскольку он имеет unique_ptr в качестве одного из членов. Я пытаюсь построить эту карту, используя std :: initializer_list, но получаю огромную ошибку, заканчивающуюся "использованием удаленной функции" constexpr std :: pair <_T1, _T2> :: pair (const std :: pair <_T1, _T2> &) ". Если я правильно понимаю, причина в том, что члены списка не являются временными, а являются постоянными ссылками, и поэтому вы просто не можете их перемещать ни неявным, ни явным образом.

Здесь является частью заголовка:

class ExitMessage {
public:
    ...
    ExitMessage( const std::string& text, 
                 std::initializer_list<std::map<std::string, ExitMessage>::value_type> subMessages);
    ...
private:
    std::string _text;
    std::unique_ptr<std::map<std::string, ExitMessage>> _subMessages;
    ...
};

И это проблема c конструктор:

ExitMessage::ExitMessage( const std::string& text,
                          std::initializer_list<std::map<std::string, ExitMessage>::value_type> subMessages )
    : _text( text ), _subMessages( new std::map<std::string, ExitMessage>( subMessages ) ) { }

Итак, что я могу сделать, чтобы можно было создавать экземпляры этот класс с использованием std :: initializer_list?

1 Ответ

0 голосов
/ 06 августа 2020

Итак, я немного поработал над конструктором и сам смог придумать решение. Поскольку мои объекты не копируются, не было недостатков в том, чтобы сделать второй аргумент пары initializer_list rvalue.

std::initializer_list<std::pair<const std::string, ExitMessage&&>>

Однако теперь я не мог использовать конструктор по умолчанию для карту, поэтому мне пришлось самому написать инициализацию l oop.

ExitMessage::ExitMessage( const std::string& text,
                          std::initializer_list<std::pair<const std::string, ExitMessage&&>>&& subMessages )
    : _text( text ) {
    _subMessages = std::make_unique<std::map<std::string, ExitMessage>>();

    for (const std::pair<const std::string, ExitMessage&&>& subMessage : subMessages) {
        auto& subMessageRef = const_cast<std::pair<const std::string, ExitMessage&&>&>(subMessage);
        _subMessages->emplace( subMessageRef.first, std::move( subMessageRef.second ) );
    }
}

Теперь я уверен, что объекты параметров являются либо временными, либо явно перемещенными (это все еще было требованием раньше из-за конструктор удаленной копии, но не для самого списка), я могу безопасно разделить элементы initializer_list и вручную переместить их на карту.

...