variadic_templates.h
#ifndef __VARIADIC_TEMPLATES__H__
#define __VARIADIC_TEMPLATES__H__
#include <iostream>
using namespace std;
namespace anl
{
// =============== tuple 存储不同类型的数据 ======================//
template<typename... TList> class tuple;
template<> class tuple<>{};
template<typename T, typename... TList>
class tuple<T, TList...>
: private tuple<TList...>
{
public:
typedef T value_type;
typedef tuple<TList...> base_type;
typedef tuple<T, TList...> this_type;
public:
tuple(const T& v, const TList&... tails)
: base_type(tails...)
, _value(v)
{
cout << "tuple(const T& v, const TList&... tails) " << v << endl;
}
tuple(const T&& v, const TList&&... tails)
: base_type(std::forward<const TList>(tails)...)
, _value(v)
{
cout << "tuple(const T&& v, const TList&&... tails) " << v << endl;
}
/*
// 本来是想使用下面的两个构造函数, 但是测试的时候发现有bug
// 在递归构造的时候, 第一次触发构造方式第一参数是右值以后, 后面的都会进入第一参数是右值的构造
// 最后只能要不全是右值的, 要不就全不是右值 来处理
tuple(const T& v, const TList&... tails)
: base_type(std::forward<const TList>(tails)...)
, _value(v)
{
cout << "tuple(const T& v, const TList&... tails) " << v << endl;
}
tuple(const T&& v, const TList&... tails)
: base_type(std::forward<const TList>(tails)...)
, _value(v)
{
cout << "tuple(const T&& v, const TList&... tails) " << v << endl;
}
*/
tuple(const this_type& other)
:base_type(static_cast<const base_type&>(other))
, _value(other._value)
{
cout << "tuple(const this_type& other) " << other._value << endl;
}
tuple(const this_type&& other)
:base_type(static_cast<const base_type&&>(other))
, _value(other._value)
{
std::cout << "tuple(const this_type&& other) " << other._value << endl;
}
const T& head() const { return _value; }
T& head() { return this->_value; }
this_type& operator = (const this_type& other)
{
cout << "this_type& operator = (const this_type& other) " << other._value << endl;
base_type::operator = (static_cast<const base_type&>(other));
_value = other._value;
return *this;
}
this_type& operator = (this_type&& other)
{
cout << "this_type& operator = (this_type&& other) " << other._value << endl;
base_type::operator = (std::move(static_cast<base_type>(other)));
_value = other._value;
return *this;
}
protected:
T _value;
};
// =============== 获取第N个数据的类型 ======================//
template<unsigned int N, typename... TList> struct tuple_at;
template<unsigned int N, typename T, typename... TList>
struct tuple_at< N, tuple<T, TList...> >
{
typedef typename tuple_at< N - 1, tuple<TList...> >::value_type value_type;
typedef typename tuple_at< N - 1, tuple<TList...> >::tuple_type tuple_type;
};
template<typename T, typename... TList>
struct tuple_at< 0, tuple<T, TList...> >
{
typedef typename T value_type;
typedef typename tuple<T, TList...> tuple_type;
};
// =============== tuple_get: 取出第N个数据 ======================//
template<unsigned int N, typename... TList>
const typename tuple_at<N, tuple<TList...> >::value_type&
tuple_get(const tuple<TList...>& tp)
{
typedef tuple<TList...> tuple_type;
typedef typename tuple_at<N, tuple_type>::tuple_type base_tuple_type;
return static_cast<const base_tuple_type&>(tp).head();
}
template<unsigned int N, typename... TList>
typename tuple_at<N, tuple<TList...> >::value_type&
tuple_get(tuple<TList...>& tuple_)
{
typedef tuple<TList...> tuple_type;
typedef typename tuple_at<N, tuple_type >::tuple_type base_tuple_type;
return static_cast<base_tuple_type&>(tuple_).head();
}
// =============== makeTuple: 创建tuple ======================//
template<typename... Type>
tuple<Type...> makeTuple(const Type&... args)
{
std::cout << "tuple<Type...> makeTuple(const Type&... args) " << endl;
return tuple<Type...>(args...);
}
template<typename... Type>
tuple<Type...> makeTuple(const Type&&... args)
{
std::cout << "tuple<Type...> makeTuple(const Type&&... args)" << endl;
return tuple<Type...>(std::forward<const Type>(args)...);
}
}
#endif
main.cpp
#include <iostream>
#include "Classes/variadic_templates.h"
int main()
{
int v[] = { 1, 2, 3};
cout << "===== 1" << endl;
auto tp1 = anl::tuple<int, int, int>(1, 2, 3);
cout << "===== 2" << endl;
auto tp2 = anl::tuple<int, int, int>(1, v[1], 3);
cout << "===== 3" << endl;
auto tp3 = anl::tuple<int, int, int>(v[0], 2, v[2]);
cout << "===== 4" << endl;
auto tp4 = anl::tuple<int, int, int>(v[0], v[1], v[2]);
cout << "===== 5" << endl;
auto tp5 = tp1;
cout << "===== 6" << endl;
auto tp6(tp2);
cout << "===== 7" << endl;
auto tp7 = std::move(tp3);
cout << "===== 8" << endl;
auto tp8(std::move(tp4));
cout << "===== 9" << endl;
auto tp11 = anl::makeTuple(1, 2, 3);
cout << "===== 10" << endl;
auto tp12 = anl::makeTuple(1, v[1], 3);
cout << "===== 11" << endl;
auto tp13 = anl::makeTuple(v[0], 2, v[2]);
cout << "===== 12" << endl;
auto tp14 = anl::makeTuple(v[0], v[1], v[2]);
cout << "===== 13" << endl;
return 0;
}
感谢 饭后温柔 http://www.cnblogs.com/flytrace/p/3574647.html
在他的基础上做了一些修改
1. 添加了makeTuple方法
2. 删掉了一些自己觉得没用的代码
3. 改了一些右值可能产生的bug
4. 添加了打印