Identifying primitive types in templates

后端 未结 8 811
南旧
南旧 2020-11-27 17:40

I am looking for a way to identify primitives types in a template class definition.

I mean, having this class :

template
class A{
void         


        
相关标签:
8条回答
  • 2020-11-27 18:39

    The following example (first posted in comp.lang.c++.moderated) illustrates using partial specialisation to print things differently depending on whether or not they are built-in types.

    // some template stuff
    //--------------------
    #include <iostream>
    #include <vector>
    #include <list>
    
    using namespace std;
    
    // test for numeric types
    //-------------------------
    template <typename T> struct IsNum {
        enum { Yes = 0, No = 1 };
    };
    
    
    template <> struct IsNum <int> { 
        enum { Yes = 1, No = 0 };
    };
    
    
    template <> struct IsNum <double> {
        enum { Yes = 1, No = 0 };
    };
    
    // add more IsNum types as required
    
    // template with specialisation for collections and numeric types
    //---------------------------------------------------------------
    template <typename T, bool num = false> struct Printer {
        void Print( const T & t ) {
            typename T::const_iterator it = t.begin();
            while( it != t.end() ) {
                cout << *it << " ";
                ++it;
            }
            cout << endl;
        }
    };
    
    template <typename T> struct Printer <T, true> {
        void Print( const T & t ) {
            cout << t << endl;
        }
    };
    
    // print function instantiates printer depoending on whether or
    // not we are trying to print numeric type
    //-------------------------------------------------------------
    template <class T> void MyPrint( const T & t ) {
        Printer <T, IsNum<T>::Yes> p;
        p.Print( t );
    }
    
    // some test types
    //----------------
    typedef std::vector <int> Vec;
    typedef std::list <int> List;
    
    // test it all
    //------------
    int main() {
    
        Vec x;
        x.push_back( 1 );
        x.push_back( 2 );
        MyPrint( x );        // prints 1 2
    
        List y;
        y.push_back( 3 );
        y.push_back( 4 );
        MyPrint( y );        // prints 3 4
    
        int z = 42;
        MyPrint( z );        // prints 42
    
        return 0;
    }
    
    0 讨论(0)
  • UPDATE: Since C++11, use the is_fundamental template from the standard library:

    #include <type_traits>
    
    template<class T>
    void test() {
        if (std::is_fundamental<T>::value) {
            // ...
        } else {
            // ...
        }
    }
    

    // Generic: Not primitive
    template<class T>
    bool isPrimitiveType() {
        return false;
    }
    
    // Now, you have to create specializations for **all** primitive types
    
    template<>
    bool isPrimitiveType<int>() {
        return true;
    }
    
    // TODO: bool, double, char, ....
    
    // Usage:
    template<class T>
    void test() {
        if (isPrimitiveType<T>()) {
            std::cout << "Primitive" << std::endl;
        } else {
            std::cout << "Not primitive" << std::endl;
        }
     }
    

    In order to save the function call overhead, use structs:

    template<class T>
    struct IsPrimitiveType {
        enum { VALUE = 0 };
    };
    
    template<>
    struct IsPrimitiveType<int> {
        enum { VALUE = 1 };
    };
    
    // ...
    
    template<class T>
    void test() {
        if (IsPrimitiveType<T>::VALUE) {
            // ...
        } else {
            // ...
        }
    }
    

    As others have pointed out, you can save your time implementing that by yourself and use is_fundamental from the Boost Type Traits Library, which seems to do exactly the same.

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