How to build this c++ typelist into a variant?

前端 未结 2 540
南笙
南笙 2021-01-26 04:53

Here,

how do I fix this c++ typelist template compile error?

we built a typelist, using the code from modern c++ design.

Question is now -- how do I take

2条回答
  •  萌比男神i
    2021-01-26 05:09

    /*
     * variant_modern.hpp
     *
     *  Created on: Jun 4, 2010
     *      Author: vvenedik
     */
    
    #ifndef _VARIANT_MODERN_HPP_
    #define _VARIANT_MODERN_HPP_
    
    struct NullType {} ;
    template 
    struct TypeList
    {
        typedef T Head;
        typedef U Tail;
    };
    
    #define TYPELIST_1(T1) TypeList 
    #define TYPELIST_2(T1, T2) TypeList 
    #define TYPELIST_3(T1, T2, T3) TypeList 
    #define TYPELIST_4(T1, T2, T3, T4) TypeList 
    #define TYPELIST_5(T1, T2, T3, T4, T5) TypeList 
    #define TYPELIST_6(T1, T2, T3, T4, T5, T6) TypeList 
    #define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) TypeList 
    #define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) TypeList 
    #define TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) TypeList
    
    namespace vlad
    {
        namespace modern
        {
    
            template  struct MaxSize ;
            template <>
            struct MaxSize
            {
                enum { value = 0 } ;
            } ;
    
            template 
            struct MaxSize< TypeList >
            {
            private :
                enum { tailValue = size_t(MaxSize::value) } ;
            public:
                enum { value = sizeof(Head) > tailValue ? sizeof(Head) : tailValue } ;
            } ;
    
            //TL Length
            template  struct Length ;
            template <>
            struct Length
            {
                 enum { value = 0 } ;
            } ;
            template 
            struct Length< TypeList >
            {
                enum { value = 1 + Length::value } ;
            } ;
    
            //TL IndexOf
            template  struct IndexOf ;
            template 
            struct IndexOf
            {
                //if not found IndexOf == max_num_of_t
                enum { value = -1 };
            };
    
            template 
            struct IndexOf,T>
            {
                    enum { value = 0 };
            };
    
            template 
            struct IndexOf,T>
            {
              private:
                    enum { nextVal = IndexOf::value };
              public:
                    enum { value = nextVal == -1 ? -1 : 1 + nextVal } ;
            };
    
            template  struct TypeAt ;
    
             template 
             struct TypeAt, 0>
             {
                  typedef Head type;
             };
    
             template 
             struct TypeAt, i>
             {
                 typedef typename TypeAt::type type;
             };
    
            template 
            class Variant
            {
            public :
                //compute the needed buffer size
                enum { max_size_t = MaxSize::value } ;
                enum { max_num_of_t = Length::value } ;
                //struct for alignment
                typedef struct { unsigned char buf_t[max_size_t] ; } base_t ;
    
                //default constructor
                template 
                explicit Variant() : _type_index(0)
                {
                    new (&_variant_holder) TypeAt::type() ;
                }
                virtual ~Variant() { } ; //{  _type_ptr->~T() ;  }
    
                template 
                explicit Variant( const T &t )
                {
                    _type_index = IndexOf::value ;
                    if ( _type_index == max_num_of_t )
                        throw std::bad_cast() ;
                    new (&_variant_holder) T(t) ;
                }
    
                template 
                const T & get() { 
                    std::size_t  type_index = IndexOf::value ;
                    if ( type_index == max_num_of_t  || type_index != _type_index)
                        throw std::bad_cast() ;
                    T * _type_ptr = reinterpret_cast(&_variant_holder) ;
                    return *_type_ptr ; 
                }
    
            private :
                base_t _variant_holder ;
                std::size_t _type_index ;
            };
    
        } //namespace modern
    }//namespace vlad
    
    
    #endif /* _VARIANT_MODERN_HPP_ */
    

    Use case :

    typedef modern::vlad::Variant variant_t;
    variant_t v (123) ;
    int value = v.get() ;
    std::string tmp = v.get() ; //throws exception
    

提交回复
热议问题