I have a working piece of C 17 code that I would like to port to C 14 (project's constraints). The code allocates a functor on the heap, based on the lambda returned by a provider.
decltype(auto) fun_provider(std::string msg)
{
return [msg](){ std::cout << msg << std::endl; };
}
int main()
{
auto fun = std::make_unique<
std::invoke_result_t<decltype(fun_provider), std::string>
>(fun_provider("Provided functor"));
(*fun.get())()
}
// output: "Provided functor"
The point is, it avoids hardcoding lambda type as std::function<void()>
. Up to my best knowledge, the closure type is unspecified and such construction would imply unnecessary copy of the closure object (hope that's correct).
I would like to achieve the same goal with C 14, is it possible? I tried few constructions with std::result_of
and/or decltype
but didn't succeed so far.
CodePudding user response:
Is this approach not viable?
auto fun = std::make_unique<
decltype(fun_provider(std::declval<std::string>()))
>(fun_provider("Provided functor"));
The use of std::declval
isn't even necessary; std::string{}
instead of std::declval<std::string>()
is just fine.
CodePudding user response:
How about routing fun_provider
's return value through another pass of template deduction?
template <class T>
auto to_unique(T&& orig) {
using BaseType = std::remove_cv_t<std::remove_reference_t<T>>;
return std::make_unique<BaseType>(std::forward<T>(orig));
}
int main()
{
auto fun = to_unique(fun_provider("Provided functor"));
(*fun.get())();
}