我有这个功能模板
template < class TParam >
bool greaterThan (TParam A, TParam B) {
if (typeid(TParam) == typeid(string)) {
return A.compare(B) > 0; <--------------- Error
} else {
return A > B;
}
}
但编译器不允许我使用int
。
我在上面显示的位置
中遇到编译器错误Member reference base type 'int' is not a structure or union.
如果我在int
上调用该函数,则if语句不会运行。
我评论出来并检查了一下。我不知道什么是错的。
答案 0 :(得分:2)
当TParam
为int
时,请执行以下操作:
A.compare(B)
您正在尝试调用compare
的{{1}}方法。这种方法不存在。你需要的是template specialisation,以便当类型是某种类型时,你可以让模板做一些特别的事情:
int
语法有点外来,但如果你读到它,模板专业化是模板的一个非常强大的补充。
请注意,template<class TParam>
bool greaterThan(TParam A, TParam B) {
return A > B; // this will be called for any type except string because of
// our following specialisation
}
// make a specialisation for when the template parameter is string
template<>
bool greaterThan<string>(string A, string B) {
return A.compare(B) > 0;
}
确实有string
,因此如果您不愿意,甚至不需要专门化它,但这是了解模板专业化的好机会。
答案 1 :(得分:2)
您知道您没有在compare
上调用int
,但编译器没有:在运行时评估您的if
。
由于string
是模板中唯一的特例,请尝试以下操作:
template < class TParam >
bool greaterThan (TParam A, TParam B) {
return A > B;
}
bool greaterThan(const string& a, const string& b) {
return a.compare(b) > 0;
}
答案 2 :(得分:1)
模板代码在编译时生成,因此if()语句尚未执行。
这个有两个解决方案
a)为int的
提供模板的专用版本b)不要使用Compare() - 并且要求struct / classes提供比较运算符。
答案 3 :(得分:1)
调用模板函数会导致编译器实例化整个函数,导致错误的语句显然不适用于int
个参数。有两种方法可以将这两种情况分开:
首先,使用greaterThan
的专精作为字符串:
template < class TParam >
bool greaterThan (TParam A, TParam B) {
return A > B;
}
template<>
bool greaterThan< string > (string A, string B) {
return A.compare(B) > 0;
}
其次,使用greaterThan
的重载作为字符串:
template < class TParam >
bool greaterThan (TParam A, TParam B) {
return A > B;
}
bool greaterThan (string const & A, string const & B) {
return A.compare(B) > 0;
}
在这两个选项中,决定调用哪个函数是在编译时进行的,而不是在运行时检查类型。但请注意,重载通过 reference 接受参数,而专门化通过 value 接受参数,因为它必须与基本模板函数的签名完全匹配。
此外,对于特化,编译器选择的函数有时可能是意外的。由于功能模板只能显式专用(即不是部分专用),因此重载提供了所有优点,并没有与专业化相关的缺点。
有关详细信息,请参阅Herb Sutter的“Why Not Specialize Function Templates?”。