c++ 11 tuple实现

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. 添加了打印

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值