Imagine we have a template class. Something like this
template<typename T>
class MyTemplateClass {
private:
T _v1, _v2;
public:
MyTemplateClass(T v1, T v2)
{
_v1 = v1;
_v2 = v2;
}
bool Act()
{
return _v1 > _v2;
}
};
//usage
MyTemplateClass<int> test(1, 2);
std::cout << test.Act() << std::endl;
now we want to pass a functor object / function pointer / lambda to his constructor so that we can use it.
I've tried something like this, but got runtime-error
template<typename T, typename F>
class MyTemplateClass {
private:
T _v1, _v2;
const F& _func;
public:
MyTemplateClass(T v1, T v2, F functor)
:_func(functor)
{
_v1 = v1;
_v2 = v2;
}
bool Act()
{
return _func(_v1, _v2);
}
};
bool isGreater(int a, int b)
{
return a > b;
}
//later
MyTemplateClass<int, std::function<bool(int, int)>> test(1, 2, isGreater);
std::cout << test.Act() << std::endl;
so how could I achieve this functionality? Is there any way to make this working without using std::function and without passing typename for my functor object? I would like to use it this way
MyTemplateClass<int> test(1, 2, isGreater);
I've tried something like this, but got runtime-error
As Matthieu Brucher pointed out their answer you can't store _func
as a reference since the object you bind the reference to dies at the end of the constructor call. Changing to storing _func
by value will fix that.
Is there any way to make this working without using std::function and without passing typename for my functor object? I would like to use it this way
MyTemplateClass<int> test(1, 2, isGreater);
This is actually pretty easy to do. You'll still have to use a std::function
as the storage type and constructor parameter type but won't have to specify it. Utilizing a type alias we can specify the predicate type in terms of the type of the class members. That gives us
using predicate = std::function<bool(T, T)>;
and after adding it to the class we can rework it to be
template<typename T>
class MyTemplateClass {
public:
using predicate = std::function<bool(T, T)>;
MyTemplateClass(T v1, T v2, predicate functor)
:_func(std::move(functor))
{
_v1 = v1;
_v2 = v2;
}
bool Act()
{
return _func(_v1, _v2);
}
private:
T _v1, _v2;
predicate _func;
};
Which can be used now like
int main()
{
MyTemplateClass<int> test(1, 2, isGreater);
std::cout << test.Act() << std::endl;
}