C++ creating callback with perfect forwarding and lambda?

16 hours ago 3
ARTICLE AD BOX

I am learning C++2x and I am trying to implement a thread pool.

That need a task object holding the function and parameters with callback to execute the function.

Here is the task object (callback) example program.

import std; template <typename F, typename... Args> struct callback{ using return_t = std::invoke_result_t<F, Args...>; F _function; std::tuple<Args...> _paras; return_t _result; constexpr callback(F function, Args ...argument) : _function(std::move(function)), _paras(std::move(argument)...){} constexpr void operator() (){ _result = std::apply(_function, _paras); } constexpr return_t get_result(){ return _result; } }; template <typename F, typename... Args> constexpr auto make_callback(F&& function, Args&& ...argument){ using return_t = std::invoke_result_t<F, Args...>; if constexpr(std::is_same_v<void, return_t>){ return [ f = std::forward<F>(function), ...args = std::forward<Args>(argument) ]() mutable { return std::invoke(f, args...); }; } else{ return callback( std::forward<F>(function), std::forward<Args>(argument)... ); } } int main(void){ auto t2 = [](int i){ std::print("Into function t2\n"); return i * i; }; auto t3 = [](int i) { std::print("t3 Value == {}\n", i); }; auto cb1 = make_callback(t2, 2); auto cb2 = make_callback(t3, 2); cb1(); cb2(); std::print("cb1 type == {}, result == {}\n",typeid(cb1).name(), cb1.get_result()); std::print("cb2 type == {}", typeid(cb2).name()); // cb2.get_result(), no member named 'get_result'; }

Compile with g++16 and clang++20 and got the result

================================================== Building and running with: GCC (C++) ================================================== cmake --build build_gcc [4/4] Linking CXX executable temp Into function t2 t3 Value == 2 cb1 type == 8callbackIZ4mainEUliE_JiEE, result == 4 cb2 type == Z13make_callbackIRZ4mainEUliE0_JiEEDaOT_DpOT0_EUlvE_ ================================================== Building and running with: CLANG (C++) ================================================== cmake --build build_clang [4/4] Linking CXX executable temp Into function t2 t3 Value == 2 cb1 type == 8callbackIZ4mainE3$_0JiEE, result == 4 cb2 type == Z13make_callbackIRZ4mainE3$_1JiEEDaOT_DpOT0_EUlvE_

My questions:

Is this good design for task object? (maybe compare to std::function or std::Futures) Is this safe with pass by value? Is that possible to store both callback or lambda into a container to execute the operator()?
Read Entire Article