Disallow a specific function template instantiation

后端 未结 4 458
醉梦人生
醉梦人生 2021-02-05 23:59

I would like to define a template function but disallow instantiation with a particular type. Note that in general all types are allowed and the generic template works, I just w

相关标签:
4条回答
  • 2021-02-06 00:14

    If you don't want to rely on static_assert or make the code portable pre-C++0x, use this:

    template<class T>
    void func(){
        typedef char ERROR_in_the_matrix[std::is_same<T,double>::value? -1 : 1];
    }
    
    int main(){
      func<int>(); // no error
      func<double>(); // error: negative subscript
    }
    
    0 讨论(0)
  • 2021-02-06 00:22

    You could use a functor instead of a function:

    template<typename T>
    struct convert { 
        T operator()(char const * in) const { return T(); } 
    };
    template<> struct convert<double>;
    
    int main()
    {
        char const * str = "1234";
    
        int a = convert<int>()( str );
        double b = convert<double>()( str ); // error in this line
    
        return 0;
    }
    

    This will give you an error at the point of instantiation.

    By adding helper function you will get the wanted behaviour:

    template<typename T>
    struct convert_helper { 
        T operator()(char const * in) const { return T(); } 
    };
    template<> struct convert_helper<double>;
    
    template<typename T>
    T convert( char const * in ) { return convert_helper<T>()( in ); }
    
    int main()
    {
        char const * str = "1234";
    
        int a = convert<int>( str );
        double b = convert<double>( str );
    
        return 0;
    }
    
    0 讨论(0)
  • 2021-02-06 00:27

    Consider Boost disable_if and Boost TypeTraits

    Take a look at How can I write a function template for all types with a particular type trait?

    This is an example:

    #include <boost/type_traits.hpp>
    #include <boost/utility/enable_if.hpp>
    
    template<typename T>
    T convert( char const * in, 
               typename boost::disable_if<boost::is_floating_point<T>, T>::type* = 0 )
    { return T(); }
    
    
    int main()
    {
        char const * str = "1234";
    
        int a = convert<int>( str );
        double b = convert<double>( str );
        return 0;
    }
    


    This is the compilation error for the string

    double b = convert<double>( str );
    

    1>.\simple_no_stlport.cpp(14) : error C2770: invalid explicit template argument(s) for 'T convert(const char *,boost::disable_if,T>::type *)' 1> .\simple_no_stlport.cpp(5) : see declaration of 'convert'

    0 讨论(0)
  • 2021-02-06 00:29

    I would use a static assert within your function call to create the proper failure during function instantiation:

    template<typename T>
    class is_double{ static const int value = false; }
    
    template<>
    class is_double<double>{ static const int value = true; }
    
    template<typename T>
    T convert( const char *argument ){
        BOOST_STATIC_ASSERT( !is_double<T>::value );
        //rest of code
    }
    

    And that should work within a function.

    0 讨论(0)
提交回复
热议问题