Force type of C++ template

前端 未结 6 1256
难免孤独
难免孤独 2020-12-28 21:34

I\'ve a basic template class, but I\'d like to restrain the type of the specialisation to a set of classes or types. e.g.:

template 
class          


        
6条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-28 22:05

    Generally it is unnecessary to restrict which types templates can be instantiated with. Either the template is compilable with the given type (and works OK) or it isn't (and produces a compiler error without any effort on the programmer's part).


    If you need to put in restrictions, generally the types have something in common that may be described by some type traits that are already available (standard library, boost::type_traits), or you can create a new type trait for them.

    For example, here's a template class that only allows integer types, using std::numeric_limits to check it (if you write your own numeric type, you may specialize that so that it would also work with your new integer type). static_assert is C++0x only, if not available use BOOST_STATIC_ASSERT or some other trick.

    #include 
    #include 
    
    template 
    class X
    {
        static_assert(std::numeric_limits::is_integer, "X can be only instantiated with integer types");
        //...
    };
    
    int main()
    {
        X xi;
        X xc;
        //X xd;
        //X xs;
    }
    

    If you only plan to support a handful of arbitrary types with nothing in common (as is apparent from your hypothetical example), one way is to employ typelists. Again boost might make the task a lot easier, but here's how you might roll your own (this only goes half-way, additional work would be required to make declaring the typelist prettier).

    struct no_type {};
    
    template 
    struct t_list
    {
        typedef T head;
        typedef U tail;
    };
    
    //trait to check if two types are identical
    template 
    struct is_same
    {
        static const bool value = false;
    };
    
    template 
    struct is_same
    {
        static const bool value = true;
    };
    
    //compile-time recursion to check if T matches any type in list L
    template 
    struct in_type_list
    {
        static const bool value =
            is_same::value || in_type_list::value;
    };
    
    //terminates recursion
    template 
    struct in_type_list
    {
        static const bool value = false;
    };
    
    template 
    class X
    {
        typedef t_list > > allowed_types; //double, int, char
    
        //poor man's static_assert
        typedef int check_type [in_type_list::value ? 1 : -1];
        //...
    };
    
    int main()
    {
        X xc;
        X xi;
        X xd;
        //X xf;
    }
    

提交回复
热议问题