Ответ на вопрос 1
Поскольку некоторые типы копируются дорого, если вы просто делаете суммирование, которое не изменяет базовые объекты, передача по константной ссылке исключаетстоимость копирования объектов.
Например, если вы передадите по значению большое значение vector
, для вызова функции будет скопировано целое значение vector
, тогда как передача константной ссылки происходит намного быстрее ( вероятно реализовано как копия указателя).
Ответ на вопрос 2
Ваша проблема в том, что при вычислении 43 + 32.2
возвращаемое значение int
, отбрасывая десятичные части. Это связано с тем, что T
в этом контексте выводится как тип литерала 43
, то есть int
. Два решения для вашей проблемы:
- Используйте
auto
в качестве возвращаемого значения. (Если вы на C ++ 14)
template <typename T>
T Add(const T& arg_a)
{
return arg_a;
}
template <typename T, typename... Pack>
auto Add(const T& arg_a, const Pack&... arg_list)
{
return arg_a + Add(arg_list...);
}
Или, если у вас есть c ++ 17, просто используйте
сложенные выражения template <typename... Pack>
auto Add(const Pack&... arg_list)
{
return (... + arg_list);
}
Если вы используете c ++ 11, используйте
std :: common_type template <typename T>
T Add(const T& arg_a)
{
return arg_a;
}
template <typename T, typename... Pack>
typename std::common_type<T, Pack...>::type Add(const T& arg_a, const Pack&... arg_list)
{
return arg_a + Add(arg_list...);
}
Когда std::common_type
не работает (например, Add('a', 'b', 'c', 'd')
),вы все еще можете написать свой собственный дедуцирующий тип суммы в c ++ 11:
template <typename SumLeftT, typename ... Args>
struct sum_t_impl;
template <typename SumLeftT>
struct sum_t_impl<SumLeftT> {
using type = SumLeftT;
};
template <typename SumLeftT, typename FirstT, typename ... Rest>
struct sum_t_impl<SumLeftT, FirstT, Rest...> {
using type = typename sum_t_impl<decltype(std::declval<SumLeftT>() + std::declval<FirstT>()), Rest...>::type;
};
template <typename T, typename ... TArgs>
using sum_t = typename sum_t_impl<T, TArgs...>::type;
и заменить тип возвращаемого значения typename std::common_type<T, Pack...>
на sum_t<T, Pack...>
.
Это, например, работает дляПакет с char
s, где char + char -> int
.
int main()
{
auto itLocalSum = Add('a', 'b', 'c', 'd');
std::cout << typeid(itLocalSum).name() << std::endl;
std::cout << "Sum of Add: " << itLocalSum << "\n";
return 0;
}
Будет выводить: int
и 394
.