How to know if the argument that is passed to the function is a class, union or enum in c++?

前端 未结 4 421
伪装坚强ぢ
伪装坚强ぢ 2021-01-03 07:14

I want to define an operator<< for all enums, to cout the value and print that it is an enum like this:

code:

enum AnyEnum{A,B,C};
AnyEnum enm          


        
4条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-03 08:18

    Determining class types you could use the fact that member pointers exist

    template
    struct issame { };
    
    template
    struct issame { typedef void type; };
    
    template struct tovoid { typedef void type; };
    
    template
    struct isclass { static bool const value = false; };
    
    template
    struct isclass::type> {
      static bool const value = true;
    };
    

    You cannot detect the difference of an union and a non-union class. At least I don't know how, and boost doesn't know either.

    I think detecting enums could work by making sure T isn't a class, function or integral type, and then trying to assign to an integral type. You could

    template 
    struct isenum { 
      struct No { char x; };
      struct Yes { No n1; No n2; };
    
      struct nullsink {};
      static No checkI(nullsink*); // accept null pointer constants
      static Yes checkI(...);
    
      static Yes checkE(int);
      static No checkE(...);
    
      static bool const value = (sizeof(checkI(E())) == sizeof(Yes)) && 
                                (sizeof(checkE(E())) == sizeof(Yes));
    };
    
    // class
    template
    struct isenum::type> {
      static bool const value = false;
    };
    
    // reference
    template
    struct isenum {
      static bool const value = false;
    };
    
    // function (FuntionType() will error out).
    template
    struct isenum::type> {
      static bool const value = false;
    };
    
    // array (ArrayType() will error out)
    template
    struct isenum {
      static bool const value = false;
    };
    template
    struct isenum {
      static bool const value = false;
    };
    

    Quick & dirty test (works on GCC/clang/comeau):

    enum A { };
    struct B { };
    typedef int &C;
    typedef void D();
    typedef int E;
    typedef long F;
    typedef int const G;
    typedef int H[1];
    
    template
    struct confirm { typedef char x[(T::value == E) ? 1 : -1]; };
    
    int main() {
      confirm< isenum, true >();
      confirm< isenum, false >();
      confirm< isenum, false >();
      confirm< isenum, false >();
      confirm< isenum, false >();
      confirm< isenum, false >();
      confirm< isenum, false >();
      confirm< isenum, false >();
    }
    

提交回复
热议问题