Type condition in template

前端 未结 5 468
-上瘾入骨i
-上瘾入骨i 2020-12-05 06:27

Is it possible to build only some part of the code given the type of the template in C++ ? It would be something lake that :

#include 

using         


        
相关标签:
5条回答
  • 2020-12-05 06:53

    You use template specification to specify versions of your function to work differently based on its type. For example, you can make a generic version of a function that would work with most types, and make a specific version for e.g. int that will be faster. You'd do it this way:

    template <class T>
    void printType(T param)
    {
        cout<<"Generic version"<<endl;
    }
    template <>
    void printType<int>(int param)
    {
        cout<<"Int version"<<endl;
    }
    template <>
    void printType<char>(char param)
    {
        cout<<"Char version"<<endl;
    }
    //Rince and repeat.
    
    0 讨论(0)
  • 2020-12-05 06:54

    Use template specialization:

    template<typename T>
    void printType(T param)
    {
       // code for the general case - or omit the definition to allow only the specialized types
    }
    
    template<>
    void printType<char*>(char* param)
    {
       // code for char*
    }
    
    template<>
    void printType<int>(int param)
    {
       // code for int    
    }
    
    // ...
    
    0 讨论(0)
  • 2020-12-05 07:00

    Since C++17 there is a way to do exactly this with if-constexpr. The following compiles since clang-3.9.1, gcc-7.1.0, and recent MSVC compiler 19.11.25506 handles well too with an option /std:c++17.

    #include <iostream>
    #include <type_traits>
    
    template<typename T>
    void printType(T)
    {
        if constexpr (std::is_same_v<T, const char*>)
            std::cout << "const char*" << std::endl;
        else if constexpr (std::is_same_v<T, int>)
            std::cout << "int" << std::endl;
        else
            std::cout << "???" << std::endl;
    }
    
    int main()
    {
        printType("Hello world!");
        printType(1);
        printType(1.1);
        return 0;
    }
    

    Output:

    const char*
    int
    ???
    
    0 讨论(0)
  • 2020-12-05 07:08

    You can use a specialization. The preprocessor runs before all templates and cannot interact with them.

    template<typename T> void printType(T t) {
        std::cout << typeid(T).name(); // fallback
    }
    template<> void printType<char*>(char* ptr) {
        std::cout << "char*";
    }
    template<> void printType<int>(int val) {
        std::cout << "int";
    }
    
    0 讨论(0)
  • 2020-12-05 07:10

    Type traits:

    #include <iostream>
    #include <type_traits> // C++0x
    //#include <tr1/type_traits> // C++03, use std::tr1
    
    template<typename T>
    void printType(T param)
    {
      if(std::is_same<T,char*>::value)
            std::cout << "char*" << endl;
      else if(std::is_same<T,int>::value)
            std::cout << "int" << endl;
      else
            std::cout << "???" << endl;
    }
    

    Or even better yet, just overload the function:

    template<class T>
    void printType(T partam){
      std::cout << "???" << endl;
    }
    
    void printType(char* partam){
      std::cout << "char*" << endl;
    }
    
    void printType(int partam){
      std::cout << "int" << endl;
    }
    

    Partial ordering will take care that the correct function is called. Also, overloading is preferred to template specialization in the general case, see this and this artice for why. Might not apply for you if you totally have to print the type, as implicit conversions are considered for overloaded functions.

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