问题 1 的答案
由于某些类型的复制成本很高,如果您只是简单地进行求和,不会修改底层对象,那么通过 const 引用传递就可以消除复制对象的成本。
例如,如果您通过值传递一个大的vector,则整个vector 将被复制以调用该函数,而传递一个 const 引用要快得多(可能已实现作为指针副本)。
问题 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,只需使用fold expressions
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中编写自己的sum类型推导器:
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...>。
例如,这适用于带有chars 的包,其中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。