c++11 tuple實現


實現一個簡易版的c++11 tuple。

我使用的編譯器是gcc,codeblocks13.12自帶的,哪個版本我不熟gcc也沒去查。

大致看了下他家的tuple實現,多繼承,tuple之上還有2個輔助類,走的是類似loki中GenScatterHierarchy的路子。1092行代碼,不是蓋的。。。

有些強迫症,不打算用多繼承,,雖然並不會實例化來,看着鬧心。

只考慮實現到POD類型的基本支持就行了,什么右值之類的我還沒看到,就不搞了,僅供參考。

個人覺得tuple保存POD類型值就足夠了,泛濫就墮落了。

 單繼承版本確實比多繼承版本美得多了,可變模板參數真是個好東西。

為了tuple_get只需使用static_cast,tuple是public繼承的。當然私有繼承更好,只是。。。我想tuple的使用應該沒有地方會造成歧義吧。

提供了一個tuuple_get<int>(const tuple&)接口獲取指定位置的值。

 

#ifndef HI_MPL_TUPLE_H_INCLUDE
#define HI_MPL_TUPLE_H_INCLUDE

namespace hi {
    using namespace mpl::utils;
  //////////////////////////////////////////////////////////
    template<typename... TList> struct tuple;

    template<> struct tuple<> {};

    typedef tuple<> nulltuple;

    //////////////////////////////////////////////////////////
    template<typename T, typename... TList>
    struct tuple<T, TList...> : public tuple<TList...>
    {
        typedef T value_type;
        typedef tuple<TList...> base_type;
        typedef tuple<T, TList...> this_type;

        tuple(const T& v, const TList&... tails):base_type(tails...),_value(v) {}

        tuple(T&& v, TList&&... tails):base_type(std::move(tails)...), _value(std::forward<T>(v)) {}
        tuple(T&& v, TList&... tails):base_type(std::move(tails)...), _value(std::forward<T>(v)) {}
        tuple(T& v, TList&&... tails):base_type(std::move(tails)...), _value(std::forward<T>(v)) {}

        tuple(const this_type& other):base_type(static_cast<const base_type&>(other)),_value(other._value)
        {}

        tuple(this_type&& other):base_type(std::move(static_cast<base_type&>(other))),_value(std::forward<T>(other._value))
        {}

        const T& head() const { return this->_value; }
        T& head() { return this->_value; }

        this_type& operator=(const this_type& other)
        {
            base_type::operator=(static_cast<const base_type&>(other));
            _value = other._value;
            return *this;
        }

        this_type& operator=(this_type&& other)
        {
            base_type::operator=(std::move(static_cast<base_type&>(other)));
            _value = other._value;
            return *this;
        }


    protected:
        T _value;
    };

    template<typename T>
    struct tuple<T> : public nulltuple
    {
        typedef T value_type;
        typedef nulltuple base_type;
        typedef tuple<T> this_type;

        tuple(const T& v):_value(v) {}
        tuple(T&& v):_value(std::forward<T>(v)) {}

        tuple(const this_type& other):_value(other._value) {}

        tuple(this_type&& other):_value(std::forward<T>(other._value)) {}

        const T& head() const { return this->_value; }
        T& head() { return this->_value; }
        this_type& operator=(const this_type& other)
        {
            _value = other._value;
            return *this;
        }
        this_type& operator=(this_type&& other)
        {
            _value = other._value;
            return *this;
        }

    protected:
        T _value;
    };


    //////////////////////////////////////////////////////////
    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 T value_type;
        typedef tuple<T, TList...> tuple_type;
    };

    template<>
    struct tuple_at<0, nulltuple>
    {
        typedef nulltuple value_type;
        typedef nulltuple tuple_type;
    };

    //////////////////////////////////////////////////////////
    template<unsigned int N, typename... TList>
    constexpr const typename tuple_at<N, tuple<TList...> >::value_type&
    tuple_get(const tuple<TList...>& tuple_)
    {
        typedef tuple<TList...> tuple_type;
        typedef typename tuple_at<N, tuple_type>::tuple_type base_tuple_type;

        return static_cast<const base_tuple_type&>(tuple_).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();
    }
}
#endif

 

例子:

#include "TypeTuple.h"
#include <tuple>

int main()
{
    bool b;
    tuple<int, float, char> pp = {10, 0.1234, 'a'};
    b = std::is_same<tuple_at<2, tuple<int, float, char>>::value_type, char >::value;
    std::cout << "is same: " << b << std::endl;
    b = std::is_same<tuple_at<2, tuple<int, float, char>>::tuple_type, tuple<char> >::value;
    std::cout << "is same: " << b << std::endl;
    std::cout << tuple_get<0>(pp)<<" "<< tuple_get<1>(pp) <<" "<<tuple_get<2>(pp) << std::endl;
    std::tuple<int, float, char> cc{10, 0.1234, 'a'};
    std::cout << sizeof(pp) << "  " << sizeof(cc) << std::endl;
    tuple<int, float, char> ppc = pp;
    std::cout << tuple_get<0>(ppc)<<" "<< tuple_get<1>(ppc) <<" "<<tuple_get<2>(ppc) << std::endl;
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM