I was basically looking into the talk: https://youtu.be/15etE6WcvBY?t=3315
Despite the typo in her shown code, I tried myself the code for better understanding.
However MSVC and GCC was not happy to accept the code and the Clang does: https://gcc.godbolt.org/z/PYGfcK95v
Here is the code:
#include <iostream>
#include <version>
#include <type_traits>
#include <utility>
#include <string>
using namespace std::string_literals;
template<typename, std::size_t> concept Any = true;
template<typename Callable, typename... Args>
auto invoke_f_with_last(Callable&& func, Args&&... args) noexcept
{
return[&]<std::size_t... Idxs>(std::index_sequence<Idxs...>)
{
return [func](Any<Idxs> auto..., auto&& last) noexcept
{
return func(std::forward<decltype(last)>(last));
}(std::forward<Args>(args)...);
}(std::make_index_sequence<sizeof...(Args) - 1u>{});
}
template<typename... Args>
void invoke_with_last(Args&&... args) noexcept
{
invoke_f_with_last(
[](const auto& last) noexcept { std::cout << last << '\n'; }
, std::forward<Args>(args)...
);
}
int main()
{
invoke_with_last(1, 2.4f, 'd', "const char[15]", "string"s);
}
The erros from GCC:
<source>: In instantiation of 'invoke_f_with_last<invoke_with_last<int, float, char, const char (&)[15], std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(int&&, float&&, char&&, const char (&)[15], std::__cxx11::basic_string<char>&&)::<lambda(const auto:13&)>, int, float, char, const char (&)[15], std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(invoke_with_last<int, float, char, const char (&)[15], std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(int&&, float&&, char&&, const char (&)[15], std::__cxx11::basic_string<char>&&)::<lambda(const auto:13&)>&&, int&&, float&&, char&&, const char (&)[15], std::__cxx11::basic_string<char>&&)::<lambda(std::index_sequence<Idxs ...>)> [with long unsigned int ...Idxs = {0, 1, 2, 3}; std::index_sequence<Idxs ...> = std::integer_sequence<long unsigned int, 0, 1, 2, 3>]':
<source>:22:6: required from 'auto invoke_f_with_last(Callable&&, Args&& ...) [with Callable = invoke_with_last<int, float, char, const char (&)[15]
and with MSVC:
error C2672: 'operator __surrogate_func': no matching overloaded function found
message : see reference to function template instantiation 'auto invoke_f_with_last::<lambda_1>::operator ()<0,1,2,3>(std::integer_sequence<size_t,0,1,2,3>) const' being compiled
message : see reference to function template instantiation 'auto invoke_f_with_last<invoke_with_last::<lambda_1>,_Ty,float,char,const char(&)[15],std::basic_string<char,std::char_traits<char>,std::allocator<char>>>(Callable &&,_Ty &&,float &&,char &&,const char (&)[15],std::basic_string<char,std::char_traits<char>,std::allocator<char>> &&) noexcept' being compiled
1> with
1> [
1> _Ty=int,
1> Callable=invoke_with_last::<lambda_1>
1> ]
message : see reference to function template instantiation 'void invoke_with_last<int,float,char,const char(&)[15],std::string>(int &&,float &&,char &&,const char (&)[15],std::string &&)' being compiled
error C2780: 'auto invoke_f_with_last::<lambda_1>::()::<lambda_1>::operator ()(_T4...,_T5 &&) const': expects 2 arguments - 5 provided
message : see declaration of 'invoke_f_with_last::<lambda_1>::()::<lambda_1>::operator ()'
So the question is, is there anything wrong in her/ my code or is it the compilers(MSVC and GCC) does speak C++20 properly yet?