Использование функции обратного вызова шаблона в переполнении стека

Я хочу иметь функцию, которая проверяет определенные условия на основе заданной функции обратного вызова.

Считает этот код:

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 «преобразование параметра 1 из bool (int *, int) в bool (ParamType, int) невозможно»

Я там решение без использования

template< typename ParamType, Check >
void DoSmth(Check isGood, const ParamType param)

Который пропускает необходимое объявление функции проверки?

Лучшим решением было бы получить заголовок IsGood () в самой функции.

3

Решение

Использование шаблона функтора решит ваши проблемы:

template< typename Functor, typename ParamType >
void DoSmth(Functor isGood, const ParamType param){
//...
if(isGood(param, some_int_calculated_here)) doSmthElse();
}

Теперь вы можете использовать любую функцию или объект функтора, который имеет совместимую подпись (не обязательно такую, которая принимает ParamType и int в качестве параметров). В противном случае вам нужно будет использовать функции с точной подписью.

3

Другие решения

Проблема в том, что первый аргумент вашей шаблонной функции не выводим:

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)) { ...
}
1

По вопросам рекламы [email protected]