Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将enable_if与模板专门化一起使用_C++_Templates_Template Meta Programming - Fatal编程技术网

C++ 将enable_if与模板专门化一起使用

C++ 将enable_if与模板专门化一起使用,c++,templates,template-meta-programming,C++,Templates,Template Meta Programming,我想让函数获取类型名称。对于属于特定集合的类型,例如数字、几何体等,我想制作一个get_type_name函数,它使用enable_if和type trait。对于不属于特定集合的每个类型,我想专门化它自己的get\u type\u name函数。这是我的代码,我遇到以下编译器错误,无法找出原因: 错误C2668:“获取类型名称”:对重载函数的调用不明确 可以是“std::string get\u type\u name(myenable\u if::type *)'或'std::string

我想让函数获取类型名称。对于属于特定集合的类型,例如数字、几何体等,我想制作一个get_type_name函数,它使用enable_if和type trait。对于不属于特定集合的每个类型,我想专门化它自己的get\u type\u name函数。这是我的代码,我遇到以下编译器错误,无法找出原因:

错误C2668:“获取类型名称”:对重载函数的调用不明确 可以是“std::string get\u type\u name(myenable\u if::type *)'或'std::string get_type_name(void*)'

模板
结构myenable_if{};
模板
如果{typedef void type;},则结构myenable_;
模板
结构是一个数字
{
静态常量布尔值=假;
};
模板
结构是一个数字
{
静态常量布尔值=真;
};
模板
std::string get_type_name(void*v=0);
//获取特定类型的\u类型\u名称
模板
std::字符串获取类型名称(void*)
{
返回std::string(“string”);
}
//获取类型集的类型名称
模板
std::string get\u type\u name(typename myenable\u if::type*t=0)
{
返回标准::字符串(“数字”);
}
int main()
{
std::string n=get_type_name();
}

这是一个工作版本

#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;
}
#包括
#包括
#包括
#包括
模板
结构myenable_if{};
模板
如果{typedef T type;},则结构myenable_;
模板
结构是一个数字
{
静态常量布尔值=假;
};
模板
结构是一个数字
{
静态常量布尔值=真;
};
模板
std::string get\u type\u name\u helper(void*t,char)
{
返回“正常”;
}
模板
typename myenable\u if::type get\u type\u name\u helper(void*t,int)
{
返回“数字”;
}
//获取特定类型的\u类型\u名称
模板
std::string get\u type\u name\u helper(void*t,char)
{
返回std::string(“string”);
}
模板
std::string get_type_name(void*t=0)
{
返回get\u type\u name\u helper(t,0);
}
int main(){
std::string n=get_type_name();

std::cout函数不能部分专用。您这里有一个重载,编译器是正确的:第一个和第三个模板在这里都同样好。@Gernot1976那么您就知道为什么代码不能编译了。@Gernot不,谢谢您的努力。我对解决方案非常满意。我测试了它,可以添加任意类型集作为容器的类型,以及其他不属于特定集合的特定类型,它是有效的。它真的很聪明。@user152508只是好奇,为什么不使用
std::enable_if
std::is_integral
实际上我正在使用boost::enable_if和boost类型特征,但我也在尝试学习enable_if是如何工作的,所以我是这样做的在测试代码中使用它。
#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;
}