使用variadic-template函数计算多个值的平均值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用variadic-template函数计算多个值的平均值相关的知识,希望对你有一定的参考价值。
我正在尝试编写一个函数来确定任意数量的参数的平均值,所有这些参数都具有相同的类型。出于学习目的,我试图使用可变参数模板函数来做到这一点。
这是我到目前为止:
template<typename T, class ... Args>
T Mean(Args ... args)
{
int numArgs = sizeof...(args);
if (numArgs == 0)
return T(); // If there are no arguments, just return the default value of that type
T total;
for (auto value : args...)
{
total += value;
}
return total / numArgs; // Simple arithmetic average (sum divided by total)
}
当我尝试编译它(使用MS Visual Studio 2013)时,我收到以下编译错误:
error C3520: 'args' : parameter pack must be expanded in this context (test.cpp)
我应该如何正确“解包”args
参数包?我认为这是省略号的目的。
您可以在参数包扩展周围添加花括号:
template<typename T, class ... Args>
T Mean(Args ... args)
{
int numArgs = sizeof...(args);
if (numArgs == 0)
return T(); // If there are no arguments, just return the default value of that type
T total;
for (auto value : {args...})
{
total += value;
}
return total / numArgs; // Simple arithmetic average (sum divided by total)
}
这应该创建一个std::initializer_list
,然后你可以使用基于范围的循环。
@Drax的回答可能就是去这里的方式。或者,您可以递归执行此操作,具有自动推导的返回类型,因此您可以混合类型。缺点是你的代码需要更多的编译,所以下面的答案更多的是可变参数模板递归的练习。码:
#include <iostream>
using namespace std;
template<typename T>
T Mean(T head)
{
return head;
}
template<typename T, class ... Args>
T Mean(T head, Args... args)
{
auto N = sizeof...(Args);
return (head + (N)*Mean(args...)) / (N + 1);
}
int main(void)
{
cout << Mean((double)1, (int)2, (float)4) << endl; // (double) 2.3333...
}
或者,用包装纸,
#include <iostream>
using namespace std;
template<typename T>
T Mean_wrapper(T head)
{
return head;
}
// return type is the type of the head of param list
template<typename T, class ... Args>
T Mean_wrapper(T head, Args... args)
{
return head + Mean_wrapper(args...);
}
template<typename T, class ... Args>
T Mean(T head, Args... args)
{
return Mean_wrapper(head, args...) / (sizeof...(args) + 1);
}
int main(void)
{
cout << Mean((double)10, (int)20, (float)30) << endl; // (double) 20
}
请注意,您可以将包扩展为标准容器,并使用常用算法来获得结果。
template <typename T, class... Args, std::size_t N = sizeof...(Args)>
T Mean(Args... args) {
std::array<T, N> arr = {args...};
if (N > 0) return std::accumulate(std::begin(arr), std::end(arr), T{}) / N;
return T{};
}
递归并考虑参数类型:
#include <iostream>
#include <type_traits>
namespace Detail {
template <typename T, typename ... Args>
struct Sum;
template <typename T>
struct Sum<T> {
typedef T type;
static type apply(T value) { return value; }
};
template <typename T, typename ... Args>
struct Sum {
typedef decltype(std::declval<T>() + std::declval<typename Sum<Args...>::type>()) type;
static type apply(T a, Args ...args) {
return a + Sum<Args...>::apply(args...);
}
};
} // namespace Detail
template <typename ... Args>
typename Detail::Sum<Args...>::type sum(Args ... args) {
return Detail::Sum<Args...>::apply(args...);
}
template <typename ... Args>
typename Detail::Sum<Args...>::type mean(Args ... args) {
return Detail::Sum<Args...>::apply(args...) / sizeof...(Args);
}
int main()
{
// 2.5 / 2
std::cout << mean(int(1), double(1.5)) << '\n';
return 0;
}
以上是关于使用variadic-template函数计算多个值的平均值的主要内容,如果未能解决你的问题,请参考以下文章
pandas使用groupby函数按照多个分组变量进行分组聚合统计使用agg函数计算分组的多个统计指标(grouping by multiple columns in dataframe)
R语言使用system.time函数统计多个函数运行的累加(累计)时间计算h2o包生成的多个算法模型进行特征重要度分析累计耗费的时间
R语言使用system.time函数统计多个函数运行的累加(累计)时间计算h2o包生成的多个算法模型进行特征重要度分析累计耗费的时间
pandas使用groupby函数基于多个分组变量(多变量分组)对dataframe数据进行分组使用size函数计算每个分组的样本的个数
pandas使用groupby函数基于指定分组变量对dataframe数据进行分组len函数和nunique函数计算分组的个数(分组包含多个dataframe)