GCC and MSVC complaints about getting the last element from the parameter pack?

103 Views Asked by At

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?

0

There are 0 best solutions below