变长参数模板

本文深入探讨了C++编程中变长参数模板的概念和使用,包括如何定义和实例化变长参数模板,以及它们在函数模板和类模板中的应用。通过示例代码,展示了如何实现可变参数的函数调用,以及变长参数在泛型编程中的强大功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include "stdafx.h"
#include "stdarg.h" 

#include <iostream>
#include <functional>
#include <vector>

using namespace std;

/************************************************************************/
/* Title: 变长参数模板 示例                                              */
/* Environment:VS2013Update4                                           */
/* Author: kagula                                                       */
/* Keyword: Variadic templates, Parameter pack, extension pack          */
/* Date: 2015-07-20                                                     */
/* Remark:参考资料不够准确,在它基础上对样本做了修改                       */
/* Reference: 《C 可变长参数 VS C++11 可变长模板》                        */
/*             http://blog.youkuaiyun.com/zj510/article/details/36633603      */
/************************************************************************/

double Sum(int count, ...)
{
	va_list ap;//need include stdarg.h file
	double sum = 0;

	va_start(ap, count);

	for (int i = 0; i < count; ++i)
	{
		double arg = va_arg(ap, double);
		sum += arg;
	}

	va_end(ap);

	return sum;
}

//////////////////////////////////////////////////////////////////////////
// parameter pack 使用方式一
// Variadic template 代表了 零个或多个template
// Variadic template 的定义 typename...
// Variadic template 的“变量” Tail...
// 下面是第一个例子
//////////////////////////////////////////////////////////////////////////
template<typename... A> class BMW{}; // 边界

template<typename First, typename... Args>
class BMW<First, Args...> : public BMW < Args... >
{
public:
	BMW()
	{
		printf("type: %s\n", typeid(First).name());
	}
private:
	First head;
};


BMW<int, char, float> car;

//////////////////////////////////////////////////////////////////////////
// parameter pack 使用方式二
//////////////////////////////////////////////////////////////////////////
template<typename... T> double Sum2(T... first)  // 边界
{
	return 0;
}

template<typename T, typename... Args> double Sum2(T first, Args... arg)
{
	double ret = first + Sum2(arg...);

	return ret;
}

//////////////////////////////////////////////////////////////////////////
// parameter pack 使用方式二的变形
//////////////////////////////////////////////////////////////////////////
template<typename T> T Sum3(T v) {
	return v;
}

template<typename T, typename... Args> T Sum3(T first, Args... args) {
	return first + Sum3(args...);
}

//////////////////////////////////////////////////////////////////////////
// parameter pack 在 lambda 中的应用
// lambda 同 std::function是两种不同的类型。
// 所以下面是 lambda 转 std::function 的示例。
//////////////////////////////////////////////////////////////////////////
template <typename T>
struct function_traits
	: public function_traits < decltype(&T::operator()) >
{};

template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits < ReturnType(ClassType::*)(Args...) const > {
	typedef function<ReturnType(Args...)> f_type;
};

template <typename L>
typename function_traits<L>::f_type make_function(L l){
	return (typename function_traits<L>::f_type)(l);
}

template <typename A, typename B>
vector<B> map(std::function<B(A)> f, vector<A> arr) {
	vector<B> res;
	for (size_t i = 0; i < arr.size(); i++) res.push_back(f(arr[i]));
	return res;
}

int _tmain(int argc, _TCHAR* argv[])
{
	//
	double sum = Sum(4, 1.0, 2.0, 3.0, 4.0);

	cout << "C Syntax: " << sum << endl;

	//
	double ret2 = Sum2(1.0, 2.0, 3.0, 4.0);
	cout << "C++11 Syntax: " << ret2 << endl;

	//
	double ret3 = Sum3(1.0, 2.0, 3.0, 4.0);
	cout << "C++11 Syntax2: " << ret3 << endl;

	//下面这段代码,只是演示 variadic template with lambda
	//实践上,更适合用C++ GPU技术来处理
	vector<int> a = { 1, 2, 3 };
	vector<int> result = map(make_function([](int x) -> int { return x*x; }), a);
	for each (auto var in result)
	{
		cout << var << endl;
	}

	//
	cin.get();

	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kagula086

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值