Итак, у меня есть std::map< std::string, boost::any >
называется OptionsMap
и я хочу создать функцию, которая принимает любой тип (следовательно, шаблон) и сохраняет его на карте.
Будет ли следующий код работать?
template <typename T>
void Set(std::string optionName, T&& optionValue)
{
OptionsMap[optionName] = optionValue;
}
Как правило, когда шаблон функции принимает универсальную ссылку (т. Е. Ссылку 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=
принимает аргумент любого типа данных, удовлетворяющий Тип ценности.
Я бы просто взял значение и переместил его для прямой совместимости, когда boost::any
начинает поддерживать семантику ходов.
template <typename T>
void Set(std::string optionName, T optionValue)
{
OptionsMap[optionName] = std::move(optionValue);
}
Передача значения этой функции переместит это когда это подвижно. Это гарантировано стандартом.