C++11 Compare types of two variables or a variable against a type

602 Views Asked by At

In summary, I would like to be able to check if the type of an object matches some type or if two objects match types.

The essence of what I'm trying to do is pasted below:

    #include <vector>
    #include <iostream>
    #include <type_traits>

    template< class T1, class T2 >
    bool compare_types(T1, T2)
    {
        return std::is_same<T1, T2>::value;   
    }

    class OBJ
    {
        
    };

    int main(int argc, char *argv[])
    {               

        OBJ a;
        OBJ b;
        int c;
        
        
        std::cout<<"\n"<<compare_types(a, b)<<"\n"; // ok and returns true
        //std::cout<<"\n"<<compare_types(c, int)<<"\n"; // compile error, ideally return true
        //std::cout<<"\n"<<std::is_same<c, int>::value<<"\n"; // compile error, ideally return trues
        //std::cout<<"\n"<<compare_types(a, OBJ)<<"\n"; // compile error, ideally return true
        //std::cout<<"\n"<<std::is_same<a, OBJ>::value<<"\n"; // compile error, ideally return true
        //std::cout<<"\n"<<compare_types(a, std::vector)<<"\n"; // compile error, ideally return false
        //std::cout<<"\n"<<std::is_same<a, b>::value<<"\n"; // compile error, ideally return true
        //std::cout<<"\n"<<std::is_same<a, c>::value<<"\n"; // compile error, ideally return false
        //std::cout<<"\n"<<std::is_same<int, float>::value<<"\n"; // compile error, ideally return false
        std::cout<<"\n"<<std::is_same<int, std::int32_t>::value<<"\n"; // ok and returns true
        
        return 0;        
    }
1

There are 1 best solutions below

0
Ted Lyngmo On
  • Function arguments should be instances. int is not an instance. It's a type.
  • Template parameters can be types (and non-types).

So, you need to pass an instance of int to your compare_types:

    std::cout << compare_types(c, int{}) << '\n';

And a type when you use c as a template parameter. Fortunately, decltype(c) provides the type:

    std::cout << std::is_same<decltype(c), int>::value << '\n';

Continue this pattern and your program would look like:

#include <iostream>
#include <type_traits>
#include <vector>

template<class T1, class T2>
bool compare_types(T1, T2) {
    return std::is_same<T1, T2>::value;
}

class OBJ {};

int main(int argc, char* argv[]) {
    OBJ a;
    OBJ b;
    int c;

    std::cout << compare_types(a, b) << '\n'
              << compare_types(c, int{}) << '\n'
              << std::is_same<decltype(c), int>::value << '\n'
              << compare_types(a, OBJ{}) << '\n'
              << std::is_same<decltype(a), OBJ>::value << '\n'
              << std::is_same<decltype(a), decltype(b)>::value << '\n'
              << std::is_same<decltype(a), decltype(c)>::value << '\n'
              << std::is_same<int, float>::value << '\n'
              << std::is_same<int, std::int32_t>::value << '\n';

    // std::cout << compare_types(a, std::vector) << '\n';
}

Demo

I don't know what you hope for with std::vector there. It's not a type in itself. It's a template, so it'd need at least one template parameter (or in C++17 and later versions, something that makes it possible to deduce T).