【问题标题】:using enable_if with template specialization将 enable_if 与模板特化一起使用
【发布时间】:2015-12-25 17:57:02
【问题描述】:

我想创建函数 get_type_name。对于属于某个集合示例的类型是数字、几何等,我想做一个 get_type_name 函数,它使用具有类型特征的 enable_if。对于不属于特定集合的每种类型,我想专门化其自己的 get_type_name 函数。这是我的代码,我得到以下编译器错误,不知道为什么:

错误 C2668:“get_type_name”:对重载函数的模糊调用 可能是 'std::string get_type_name(myenable_if::type *)' 或 '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>();

}

【问题讨论】:

  • 函数不能部分特化。你这里有一个重载并且编译器是正确的:第一个和第三个模板在这里同样好。
  • @Gernot1976 那么你知道为什么代码不能编译了。
  • @Gernot no, they cannot be

标签: c++ templates template-meta-programming


【解决方案1】:

这是一个工作版本。

#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;
}

Live Demo

【讨论】:

  • 感谢您的努力。我对解决方案非常满意。我对其进行了测试,我可以添加任意类型的集合,比如容器类型,以及不属于特定集合的其他特定类型,并且它可以工作。真是聪明。
  • @user152508 只是好奇,你为什么不用std::enable_ifstd::is_integral
  • 实际上我正在使用 boost::enable_if 和 boost 类型特征,但我也试图了解 enable_if 的工作原理,所以我在测试代码中使用了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-13
  • 2014-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
相关资源
最近更新 更多