I am trying to implement a recursive version std::invoke_result_t
with C++20 concept so that the type of nested invoke result can be retrieved.
The use case of recursive_invoke_result_t
auto f1 = [](int x) { return static_cast<double>(x); };
std::cout << typeid(recursive_invoke_result_t<decltype(f1), int>).name() << std::endl; // expected output "double"
std::cout << typeid(recursive_invoke_result_t<decltype(f1), std::vector<int>>).name() << std::endl; // expected output is something like "std::vector<double>"
std::cout << typeid(recursive_invoke_result_t<decltype(f1), std::vector<std::vector<int>>>).name() << std::endl; // expected output is something like "std::vector<std::vector<double>>"
auto f2 = [](int x) { return std::to_string(x); };
std::cout << typeid(recursive_invoke_result_t<decltype(f2), std::vector<int>>).name() << std::endl; // expected output is something like "std::vector<string>"
auto f3 = [](std::string x) { return std::atoi(x.c_str()); };
std::cout << typeid(recursive_invoke_result_t<decltype(f3), std::vector<std::string>>).name() << std::endl; // expected output is something like "std::vector<int>"
The experimental implementation
The experimental implementation is as below.
// recursive_invoke_result_t implementation
template<typename F, typename T>
requires (std::invocable<F, T>)
struct recursive_invoke_result_t_detail
{
using type = std::invoke_result_t<F, T>;
};
template <typename F, template <typename...> typename Container, typename... Ts>
requires (std::ranges::input_range<std::ranges::range_value_t<Container<Ts...>>>) && (!std::invocable<F, Container<Ts...>>)
struct recursive_invoke_result_t_detail<F, Container<Ts...>>
{
using type = Container<typename recursive_invoke_result_t_detail<F, std::iter_value_t<Container<Ts...>>>::type>;
};
template<typename F, typename T>
using recursive_invoke_result_t = typename recursive_invoke_result_t_detail<F, T>::type;
In the above experimental implementation, the test case recursive_invoke_result_t<decltype(f1), int>
seems to be working fine. When it comes to the second test case recursive_invoke_result_t<decltype(f1), std::vector<int>>
, the compile errors 'recursive_invoke_result_t_detail': the associated constraints are not satisfied
, 'recursive_invoke_result_t' : Failed to specialize alias template
and unable to recover from previous error(s); stopping compilation
occurred. Is there any way to solve this? Please give me some hints or examples.