我想要一个基于给定回调函数检查某些条件的函数。
考虑这段代码:
class Foo{
template <class ParamType>
struct IsGood
{
typedef bool (*Check)(typename const ParamType*, int other);
};
template< typename ParamType >
void DoSmth(IsGood<ParamType>::Check isGood, const ParamType* param){
//...
if(isGood(param, some_int_calculated_here)) doSmthElse();
}
我想要的是用:
bool checkEqualInt(int* i, int j){return *i==j;}
bool checkEqualFloat(float* i, float j){return *i==j;}
DoSmth(checkEqualInt, &i);
DoSmth(checkEqualFloat, &i_float);
(显示问题的所有构造示例)
编译器不会得到它并且抛出错误C2664&#34;在bool(ParamType,int)中从bool(int *,int)转换param 1是不可能的&#34;
我没有使用
的解决方案template< typename ParamType, Check >
void DoSmth(Check isGood, const ParamType param)
哪个省略了检查功能的必要声明?
最佳解决方案是在函数本身中获取IsGood()标头。
答案 0 :(得分:3)
使用仿函数模板可以解决您的问题:
template< typename Functor, typename ParamType >
void DoSmth(Functor isGood, const ParamType param){
//...
if(isGood(param, some_int_calculated_here)) doSmthElse();
}
现在,您可以使用具有兼容签名的任何函数或仿函数对象(不一定使用ParamType
和int
作为参数。否则,您将需要使用具有该确切签名的函数。
答案 1 :(得分:2)
问题是你的模板函数的第一个参数是不可推导的:
template< typename ParamType >
void DoSmth(typename IsGood<ParamType>::Check isGood, const ParamType param)
// ^ ^^^^^^^^^^^^^^^^^^^^^^^^
// missing nested type! not deducible!
简单的选项是扩展签名(C ++ 03,C ++ 11):
template< typename ParamType >
void DoSmth(void (*isGood)(ParamType,int), const ParamType param)
// note: dropped 'const' that will be dropped anyway by the compiler
或者,如果你有C ++ 11,你可以用模板别名替换IsGood<ParamType>::Check
:
template <typename T>
using IsGood = void (*)(T,int);
template< typename ParamType >
void DoSmth(IsGood<ParamType> isGood, const ParamType param)
或者重构您的代码以使用一个仿函数,使其更灵活,更简单,更高效,因为编译器可以更容易地内联调用:
template <typename P, typename T>
void DoSmth(P predicate, T param) {
if (predicate(param,somethingelse)) { ...
}