我想创建一个排除类型字符串或char
的解析函数template <typename T>
bool parse(T & value, const string & token){
istringstream sin(token);
T t;
if( !(sin >>t) ) return false;
char junk;
if( sin >>junk ) return false;
value = t;
return true;
}
我该怎么做?
答案 0 :(得分:3)
取决于您的意思排除类型string
或char
。如果您不想链接,可以声明但不定义类型的特化:
template <>
void parse<std::string>( std::string & value, const std::string& token );
编译器将看到特化而不生成代码。链接器将失败,因为未在任何转换单元中定义符号。
第二种方法,有点复杂,不是在链接时失败,而是使编译器不接受这些类型的模板。这可以通过SFINAE来完成,这在C ++ 11中更简单,但如果您需要C ++ 03解决方案,您可以谷歌搜索它或添加注释:
template <typename T,
typename = typename std::enable_if<!std::is_same<T,std::string>
&& !std::is_same<T,char>>::type >
void parse( T & t, const std::string& token ) {
// ...
}
(我没有通过编译器运行它,所以语法可能有点关闭,玩它)编译器将看到模板,当它尝试执行类型T
的替换它将由于std::enable_if<...>::type
未解析为某种类型而失败。
通常,您可能希望提供不同的重载来执行特定版本的parse
并优先:
void parse( std::string& v, const std::string& token ) {
v = token;
}
请注意,这不是模板,而是常规功能。当调用的参数是完美匹配时,非模板化函数将比模板化函数更好地匹配。
答案 1 :(得分:0)
您可以使用提升类型特征。他们有一个名为is_same
的类型比较检查您可以将比较结果用于char和string。
答案 2 :(得分:0)
模板应该像这样声明 DavidRodríguez的方法(对于具有返回类型的函数):
template <template T, typename std::enable_if<!std::is_same<T,std::string>::value>::type* = nullptr >
T func(T x){}
对于多种情况:
template <template T, typename std::enable_if<!std::is_same<T,std::string>::value &&!std::is_same<T,int>::value>::type* = nullptr >
T func(T x){}
对于没有返回类型的函数:
template <template T>
typename std::enable_if<!std::is_same<T,std::string>::value>::type
func(T x){}
对于多种情况:
template <template T>
typename std::enable_if<!std::is_same<T,std::string>::value &&!std::is_same<T,int>::value>::type
func(T x){}
不要忘记包含#include <type_traits>