[英]How can I write a function template for all types with a particular type trait?
Consider the following example: 请考虑以下示例:
struct Scanner
{
template <typename T>
T get();
};
template <>
string Scanner::get()
{
return string("string");
}
template <>
int Scanner::get()
{
return 10;
}
int main()
{
Scanner scanner;
string s = scanner.get<string>();
int i = scanner.get<int>();
}
The Scanner
class is used to extract tokens from some source. Scanner
类用于从某些源提取令牌。 The above code works fine, but fails when I try to get
other integral types like a char
or an unsigned int
. 上面的代码工作正常,但是当我尝试get
其他整数类型(如char
或unsigned int
时失败。 The code to read these types is exactly the same as the code to read an int
. 读取这些类型的代码与读取int
的代码完全相同。 I could just duplicate the code for all other integral types I'd like to read, but I'd rather define one function template for all integral types. 我可以复制我想要阅读的所有其他整数类型的代码,但我宁愿为所有整数类型定义一个函数模板。
I've tried the following: 我尝试过以下方法:
struct Scanner
{
template <typename T>
typename enable_if<boost::is_integral<T>, T>::type get();
};
Which works like a charm, but I am unsure how to get Scanner::get<string>()
to function again. 哪个像魅力一样,但我不确定如何让Scanner::get<string>()
再次运行。 So, how can I write code so that I can do scanner.get<string>()
and scanner.get<any integral type>()
and have a single definition to read all integral types? 那么,我如何编写代码以便我可以执行scanner.get<string>()
和scanner.get<any integral type>()
并且只有一个定义来读取所有整数类型?
Update: bonus question : What if I want to accept more than one range of classes based on some traits? 更新:红利问题 :如果我想根据某些特征接受多个课程范围怎么办? For example: how should I approach this problem if I want to have three get
functions that accept (i) integral types (ii) floating point types (iii) strings, respectively. 例如:如果我想要有三个get
函数分别接受(i)整数类型(ii)浮点类型(iii)字符串,我应该如何处理这个问题。
struct Scanner
{
template <typename T>
typename boost::enable_if<boost::is_integral<T>, T>::type get()
{
return 10;
}
template <typename T>
typename boost::disable_if<boost::is_integral<T>, std::string>::type get()
{
return "string";
}
};
Update "What if I want to accept more than one range of classes based on some traits?" 更新“如果我想根据某些特征接受多个类别,该怎么办?”
struct Scanner
{
template <typename T>
typename boost::enable_if<boost::is_integral<T>, T>::type get()
{
return 10;
}
template <typename T>
typename boost::enable_if<boost::is_floating_point<T>, T>::type get()
{
return 11.5;
}
template <typename T>
std::string get(
typename boost::disable_if<boost::is_floating_point<T>, T>::type* = 0,
typename boost::disable_if<boost::is_integral<T>, T>::type* = 0)
{
return std::string("string");
}
};
Defer to another template. 推迟到另一个模板。 Here's the general pattern for what you want: 这是您想要的一般模式:
template <typename T, bool HasTrait = false>
struct scanner_impl;
template <typename T>
struct scanner_impl
{
// Implement as though the trait is false
};
template <typename T>
struct scanner_impl<true>
{
// Implement as though the trait is true
};
// This is the one the user uses
template <typename T>
struct scanner : scanner_impl<T, typename has_my_trait<T>::value>
{
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.