Reputation: 2148
I'm trying to receive lambda functions as parameters, however I'm having problem with its types.
Here's how I'm calling the function
profile(0, 1000, fps, [](ProfilerVariable<int> &fps){fps.counter++;}, [](ProfilerVariable<int> &fps){fps.counter=0;});
Here's how I defined it:
template <typename T>
void profile(int index, int intervalInMilliseconds, ProfilerVariable<T>& profilerVariable,
std::function<void(ProfilerVariable<T>&)> const &increaseFunction,
std::function<void(ProfilerVariable<T>&)> const &resetFunction)
{
increaseFunction(profilerVariable);
//...
I don't see nothing wrong. Return type is void, and it accepts ProfilerVariable&
:
/home/dev/orwell/cpp/common/ZLRTSPClient.cpp:38:26: error: no matching function for call to 'ZLRTSPClient::profile(int, int, ProfilerVariable<int>&, ZLRTSPClient::init()::<lambda(const toolkit::SockException&)>::<lambda(const Ptr&)>::<lambda(ProfilerVariable<int>&)>, ZLRTSPClient::init()::<lambda(const toolkit::SockException&)>::<lambda(const Ptr&)>::<lambda(ProfilerVariable<int>&)>)'
});
^
In file included from /home/dev/orwell/cpp/common/RTSPClient.h:11:0,
from /home/dev/orwell/cpp/common/ZLRTSPClient.h:3,
from /home/dev/orwell/cpp/common/ZLRTSPClient.cpp:1:
/home/dev/orwell/cpp/common/Profiler.h:41:10: note: candidate: template<class T> void Profiler::profile(int, int, ProfilerVariable<T>&, const std::function<void(ProfilerVariable<T>&)>&, const std::function<void(ProfilerVariable<T>&)>&)
void profile(int index, int intervalInMilliseconds, ProfilerVariable<T>& profilerVariable,
^~~~~~~
/home/dev/orwell/cpp/common/Profiler.h:41:10: note: template argument deduction/substitution failed:
/home/dev/orwell/cpp/common/ZLRTSPClient.cpp:38:26: note: 'ZLRTSPClient::init()::<lambda(const toolkit::SockException&)>::<lambda(const Ptr&)>::<lambda(ProfilerVariable<int>&)>' is not derived from 'const std::function<void(ProfilerVariable<T>&)>'
});
^
PS: what does the const
in std::function<void(ProfilerVariable<T>&)> const &increaseFunction
stands for?
Upvotes: 1
Views: 110
Reputation: 217275
lambda is not std::function
, so T
cannot be deduced.
You might get rid of std::function
and take functor:
template <typename T, typename F1, typename >
void profile(int index,
int intervalInMilliseconds,
ProfilerVariable<T>& profilerVariable,
F1 const &increaseFunction,
F2 const &resetFunction) {/*..*/}
or you can make those parameters non deducible:
template <typename T>
void profile(int index,
int intervalInMilliseconds,
ProfilerVariable<T>& profilerVariable, // Deduce T only here
std::type_identity_t<std::function<void(ProfilerVariable<T>&)>> const &increaseFunction,
std::type_identity_t<std::function<void(ProfilerVariable<T>&)>> const &resetFunction)
std::type_identity_t
is C++20 but can be implemented for previous version.
Else you have to change in the call site
be explicit:
profile<int>(0, 1000, fps, [](ProfilerVariable<int> &fps){fps.counter++;}, [](ProfilerVariable<int> &fps){fps.counter=0;});
or use "correct" arguments
profile(0,
1000,
fps,
std::function{[](ProfilerVariable<int> &fps){fps.counter++;}},
std::function{[](ProfilerVariable<int> &fps){fps.counter=0;}});
Upvotes: 2