I want to have a function that checks certain conditions based on a given callback function.
Considers this code:
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();
}
What I want is to call it with:
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);
(All constructed examples to show the problem)
The compiler won't get that and throws me error C2664 "converting param 1 from bool(int*,int) in bool(ParamType,int) not possible"
I there a solution without using
template< typename ParamType, Check >
void DoSmth(Check isGood, const ParamType param)
Which ommits the necessary declaration of the check function?
Best solution would be to get the IsGood() header in the function itself.
The problem is that the first argument of your template function is not deducible:
template< typename ParamType >
void DoSmth(typename IsGood<ParamType>::Check isGood, const ParamType param)
// ^ ^^^^^^^^^^^^^^^^^^^^^^^^
// missing nested type! not deducible!
The simple option is to expand the signature in place (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
Or if you have C++11 you can substitute the IsGood<ParamType>::Check
by a template alias:
template <typename T>
using IsGood = void (*)(T,int);
template< typename ParamType >
void DoSmth(IsGood<ParamType> isGood, const ParamType param)
Or alternatively refactor your code to take a functor that will make it more flexible, simple and possibly efficient since there will be easier for the compiler to inline the call:
template <typename P, typename T>
void DoSmth(P predicate, T param) {
if (predicate(param,somethingelse)) { ...
}