Created on 2021-12-29.00:00:00 last changed 12 months ago
Proposed resolution:
This wording is relative to N4928.
Modify [func.require] as indicated:
-1- Define INVOKE(f, t1, t2, …, tN) as follows:
- (1.1) — (t1.*f)(t2, …, tN) when f is a pointer to a member function of a class T and is_same_v<T, remove_cvref_t<decltype(t1)>> || is_base_of_v<T, remove_
referencecvref_t<decltype(t1)>> is true;- (1.2) — (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;
- (1.3) — ((*t1).*f)(t2, …, tN) when f is a pointer to a member function of a class T and t1 does not satisfy the previous two items;
- (1.4) — t1.*f when N == 1 and f is a pointer to data member of a class T and is_same_v<T, remove_cvref_t<decltype(t1)>> || is_base_of_v<T, remove_
referencecvref_t<decltype(t1)>> is true;- (1.5) — t1.get().*f when N == 1 and f is a pointer to data member of a class T and remove_cvref_t<decltype(t1)> is a specialization of reference_wrapper;
- (1.6) — (*t1).*f when N == 1 and f is a pointer to data member of a class T and t1 does not satisfy the previous two items;
- (1.7) — f(t1, t2, …, tN) in all other cases.
[ 2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP. ]
[ Issaquah 2023-02-07; LWG ]
Move to Immediate for C++23
[ 2023-02-07; Jonathan provides wording change requested by LWG ]
Change remove_reference_t to remove_cvref_t. is_base_of ignores cv-qualifiers, so this isn't necessary, but just using the same transformation in both cases seems simpler to grok.
[ 2023-02-07; Jonathan adds wording ]
This is a regression introduced by LWG 2219.
In C++14 std::result_of<int Foo::*(Foo&)>::type
was valid, because the INVOKE wording used to say
"f is a pointer to member data of a class T
and t1 is an object of type T
or a reference to an object of type T
or a reference to an object of a type derived from T".
Since LWG 2219 we use is_base_of
which is always false for
union types.
I don't think LWG 2219 intended to break this case, so we should fix it.
Previous resolution [SUPERSEDED]:
This wording is relative to N4928.
Modify [func.require] as indicated:
-1- Define INVOKE(f, t1, t2, …, tN) as follows:
- (1.1) — (t1.*f)(t2, …, tN) when f is a pointer to a member function of a class T and is_same_v<T, remove_cvref_t<decltype(t1)>> || is_base_of_v<T, remove_reference_t<decltype(t1)>> is true;
- (1.2) — (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;
- (1.3) — ((*t1).*f)(t2, …, tN) when f is a pointer to a member function of a class T and t1 does not satisfy the previous two items;
- (1.4) — t1.*f when N == 1 and f is a pointer to data member of a class T and is_same_v<T, remove_cvref_t<decltype(t1)>> || is_base_of_v<T, remove_reference_t<decltype(t1)>> is true;
- (1.5) — t1.get().*f when N == 1 and f is a pointer to data member of a class T and remove_cvref_t<decltype(t1)> is a specialization of reference_wrapper;
- (1.6) — (*t1).*f when N == 1 and f is a pointer to data member of a class T and t1 does not satisfy the previous two items;
- (1.7) — f(t1, t2, …, tN) in all other cases.
[ 2022-01-30; Reflector poll ]
Set priority to 3 after reflector poll.
There are two cases of the INVOKE operation specified with std::is_base_of_v ([func.require] (1.1), (1,4)), which means the following code snippet is ill-formed, as std::is_base_of_v<B, D> is false when either B or D is a union type.
union Foo { int x; }; static_assert(std::is_invocable_v<int Foo::*, Foo&>);
Currently libstdc++ accepts this code, because it uses slightly different conditions that handle union types. libc++ and MSVC STL reject this code as specified in [func.require].
Should we change the conditions in [func.require] (1.1) and (1.4) to match libstdc++ and correctly handle union types?History | |||
---|---|---|---|
Date | User | Action | Args |
2023-11-22 15:47:43 | admin | set | status: wp -> c++23 |
2023-02-13 11:31:32 | admin | set | messages: + msg13381 |
2023-02-13 11:31:32 | admin | set | status: immediate -> wp |
2023-02-07 18:07:56 | admin | set | messages: + msg13286 |
2023-02-07 18:07:56 | admin | set | messages: + msg13285 |
2023-02-07 18:07:56 | admin | set | status: new -> immediate |
2023-02-07 15:05:44 | admin | set | messages: + msg13284 |
2023-02-07 15:05:44 | admin | set | messages: + msg13283 |
2022-01-30 17:05:36 | admin | set | messages: + msg12326 |
2021-12-29 00:00:00 | admin | create |