Шаблоны и использование ссылок на значения в качестве параметра

Итак, у меня есть std::map< std::string, boost::any > называется OptionsMap и я хочу создать функцию, которая принимает любой тип (следовательно, шаблон) и сохраняет его на карте. Будет ли следующий код работать?

template <typename T>
void Set(std::string optionName, T&& optionValue)
{
    OptionsMap[optionName] = optionValue;
}

2 ответа

Решение

Как правило, когда шаблон функции принимает универсальную ссылку (т. Е. Ссылку на rvalue выведенного типа), вы должны привести параметр функции к forward чтобы получить значение той же категории, что и аргумент в вызове функции:

template <typename T>
void Set(std::string optionName, T&& optionValue)
{
    OptionsMap[optionName] = std::forward<T>(optionValue);
    //                       ^^^^^^^^^^^^^^^
}

Переменная параметра optionValue само по себе всегда lvalue, поэтому без приведения вы бы делали копии того, что должно быть. Если тип является копируемым, это будет менее эффективно, чем ожидалось; если тип не может быть скопирован (например, unique_ptr), это еще хуже: ваша функция теперь принимает аргумент, который впоследствии не сможет скомпилировать.

Конечно. Почему бы это не сработало?

boost::any::operator= принимает аргумент любого типа данных, удовлетворяющий ValueType.

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

template <typename T>
void Set(std::string optionName, T optionValue)
{
    OptionsMap[optionName] = std::move(optionValue);
}

Передача rvalue этой функции переместит ее, когда она станет подвижной. Это гарантировано стандартом.

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