#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.csdn.net/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; }