https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101904

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Only clang can compile it. MSVC and EDG can't:
https://godbolt.org/z/941P1vfjG

I think Clang doesn't even bother to instantiate the return type for the
non-const overload, because it wouldn't be viable. I'm not sure if that's a
conforming implementation or not.

Reduced:

namespace std
{
    template<typename, typename> constexpr bool is_same_v = false;
    template<typename T> constexpr bool is_same_v<T, T> = true;

    template<typename> using void_t = void;

    template<typename T> T&& declval();

    template<typename F, typename Arg, typename = void>
        struct result_of_impl
        { };

    template<typename F, typename Arg>
        struct result_of_impl<F, Arg,
void_t<decltype(declval<F>()(declval<Arg>()))>>
        {
            using type = decltype(declval<F>()(declval<Arg>()));
        };

    template<typename> struct result_of;

    template<typename F, typename Arg>
        struct result_of<F(Arg)>
        : result_of_impl<F, Arg>
        { };

    template<typename T> using result_of_t = typename result_of<T>::type;
}


struct ZZZ
{
    template <typename Func>
    auto foo(Func func) -> std::result_of_t<Func(int*)>
    {
        return func(static_cast<int*>(nullptr));
    }

    template <typename Func>
    auto foo(Func func) const -> std::result_of_t<Func(const int*)>
    {
        return func(static_cast<const int*>(nullptr));
    }
};

int main()
{
    const ZZZ zzz;

    zzz.foo(
        [&](auto* pointer)
            // specifying the return type explicitly will fix the issue
            //-> void
        {
            static_assert(std::is_same_v<decltype(pointer), const int*>, "");
        });
}

Reply via email to