Если вы согласны с последующими вставками с дублирующимися ключами, перезаписывающими предыдущие, то:
devices_[i] = std::move(device);
Если нет, то:
devices_.insert(std::make_pair(i, std::move(device)));
Причина, по которой последнее работает, а код в вопросе - нет, состоит в том, что до C ++ 17 метод insert
имел дефектный набор перегрузок, который вы можете увидеть здесь :
std::pair<iterator, bool> insert( const value_type& value ); // 1
template<class P>
std::pair<iterator,bool> insert( P&& value ); // 2
Обычно перегрузка # 2 должна обрабатывать случаи, когда необходимо переместить аргумент, но в вашем случае, так как вы решили передать список фигурных скобок init, список P
не может быть выведен, и # 1 выигрывает разрешение перегрузки и пытается скопировать аргумент. Используя std::make_pair
, вы можете принудительно удержать вывод для # 2, который затем выигрывает и делает правильные вещи.
В C ++ 17 это исправлено, поскольку добавлена перегрузка # 3:
std::pair<iterator,bool> insert( value_type&& value );
, которая выиграет разрешение перегрузки с аргументом braced-init-list.