C ++: function pointer as template argument instead of functor

I am trying to create this class that can either use the default functor as an argument, or the user can provide it if they want. But I cannot pass the function pointer as a template argument. Could you please help me in understanding what I am missing.

template <typename T>
struct CheckFunctor
{
    bool operator()(T obj)
    {
        return true;
    }
};



template <typename _Ty,
class _Pr = CheckFunctor<_Ty>
>
class MyClass
{
    typedef _Ty                     mapped_type;
    typedef _Pr                     CanBeCleaned_type;

    _Ty data;
    CanBeCleaned_type predicate;

public:  

    void SomeMethod()
    {
            if( predicate(data))
            {
              std::cout << "Do something";
            }
    }
       MyClass(_Ty timeOutDuration, _Pr pred = _Pr())
        : data( timeOutDuration), predicate( pred)
    {}   
};

template< typename T>
struct CheckEvenFunctor
{
   bool operator()(T val)
    {
       return (val%2 == 0);
    }
};


bool CheckEven( int val)
{
    return (val%2 == 0);
}

int main()
{
//Usage -1
    MyClass<int> obj1( 5);

//Usage- 2
 MyClass< int, CheckEven> obj2(6, CheckEven);  //Error: 'CheckEven' is not a valid template type argument for parameter '_Pr'

 //Usage -3 
 MyClass<int, CheckEvenFunctor<int>>( 7);
}

      

+3


source to share


2 answers


You are trying to pass CheckEven

as a type parameter, although CheckEven

it is not a type but a function (of a type bool(int)

). You must define the type as a pointer to the type of the passed function. decltype

it is convenient here:

MyClass< int, decltype(&CheckEven)> obj2(6, CheckEven);

      



You can also create a factory function and let the compiler infer the template parameters:

template<class T, class F>
MyClass<T, F> makeClass(T timeOutDuration, F pred) {
    return {timeOutDuration, pred};
}

auto obj2 = makeClass(6, CheckEven);

      

+3


source


It is possible to allow a template parameter to be a function, but yours MyClass

expects the second argument to be a type and not a function. You might think that template specialization could be used so that you can define MyClass

to also take a function in the second template argument, but that won't work. Template specialization allows you to change behavior MyClass

for certain types that are passed as template arguments, but those types must still conform to the template's definition MyClass

, which is that the two arguments are types.

You can change the type MyClass

you create by giving a second argument of the function pointer type as suggested in the other answer, but you will lose the benefit of extending the template making your calls to inline functions. Another solution would be to create a helper class that converts your function to a functor and uses it to instantiate it MyClass

.



template <bool P (int)>
struct F {
    bool operator()(int obj) { return P(obj); }
};

//...
MyClass<int, F<CheckEven> > obj2(6);

      

+3


source







All Articles