简体   繁体   中英

using enable_if with template specialization

I want to make function get_type_name. For types that belong to certain set example are numbers, geometry etc I want to make one get_type_name function which uses enable_if with type trait. And for each type that do not belong to particular set I want to specialize its own get_type_name function. This is my code and I get the following compiler error and can't figure out why:

error C2668: 'get_type_name': ambiguous call to overloaded function could be 'std::string get_type_name(myenable_if::type *)' or 'std::string get_type_name(void *)'

template<bool B, typename T = void>
struct myenable_if {};

template<typename T>
struct myenable_if<true, T> { typedef void type; };


template<class T>
struct is_number
{
  static const bool value = false;
};

template<>
struct is_number<int>
{
  static const bool value = true;
};

template<class T>
std::string get_type_name(void* v=0);

//get_type_name for specific type
template<>
std::string get_type_name<std::string>(void*)
{
   return std::string("string");
}

//get_type_name for set of types
template<class T>
std::string get_type_name(typename myenable_if<is_number<T>::value>::type*  t=0)
{
   return std::string("number");
}

int main()
{

   std::string n = get_type_name<int>();

}

Here is a working version.

#include <iostream>
#include <string>
#include <vector>
#include <iostream>
template<bool B, typename T = void>
struct myenable_if {};
template<typename T>
struct myenable_if<true, T> { typedef T type; };

template<class T>
struct is_number
{
  static const bool value = false;
};

template<>
struct is_number<int>
{
  static const bool value = true;
};

template<class T>
std::string get_type_name_helper(void* t, char)
{
    return "normal";
}
template<class T>
typename myenable_if<is_number<T>::value, std::string>::type get_type_name_helper(void* t, int)
{
    return "number";
}

//get_type_name for specific type
template<>
std::string get_type_name_helper<std::string>(void* t, char)
{
   return std::string("string");
}

template <class T>
std::string get_type_name(void* t = 0)
{
    return get_type_name_helper<T>(t, 0);
}
int main() {
    std::string n = get_type_name<int>();
    std::cout <<  n << '\n';
    n = get_type_name<std::string>();
    std::cout <<  n << '\n';
    n = get_type_name<float>();
    std::cout <<  n << '\n';
    return 0;
}

See Live Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM