C++ Logo

std-discussion

Advanced search

Re: Ambiguous specification of INVOKE?

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Sun, 30 Oct 2022 10:10:03 +0100
Hi,

That indeed looks ambiguous to me. I expected the typical "if A is well formed then do A else if ..." chain in the standard wording, but it's not used here.

Cheers,
Lénárd


On 30 October 2022 03:29:41 CET, Eric Schmidt via Std-Discussion <std-discussion_at_[hidden]> wrote:
>In [func.require], we have the definition of INVOKE(f, t1, t2, ..., tN), which has a number of cases. The first two are
>
>(t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and is_­base_­of_­v<T, remove_­reference_­t<decltype(t1)>> is true;
>
>and
>
>(t1.get().*f)(t2, ..., tN) when f is a pointer to a member function of a class T and remove_­cvref_­t<decltype(t1)> is a specialization of reference_­wrapper;
>
>There is no mention of which of these is to be preferred if the conditions hold in both cases.
>
>So, given
>
>using refwrap = std::reference_wrapper<int>;
>
>is std::is_invocable_v<void (refwrap::*)(), refwrap> true? If the first case takes precedence, then yes. If the second case, then no.
>
>A quick check on Godbolt shows that GCC and Clang evaluate the previous expression to false, while MSVC evaluates it to true.
>
>A similar ambiguity exists for the pointer-to-data-member case.
>
>(I had originally written the following example, which yields a compiler error on GCC and Clang, but is accepted by MSVC. But then I realized that it violates the general ban on creating pointers to library functions.)
>
>void f(std::reference_wrapper<int> x)
>{
> std::invoke(&std::reference_wrapper<int>::get, x);
>}
>--
>Std-Discussion mailing list
>Std-Discussion_at_[hidden]
>https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion

Received on 2022-10-30 09:10:23