Created on 2024-10-30.00:00:00 last changed 3 weeks ago
Suggested resolution (incomplete):
Change in 13.7.7.2 [temp.over.link] paragraph 5 as follows, adding bullets:
... For determining whether two dependent names (13.8.3 [temp.dep]) are equivalent, the following rules apply:[Note 5: If such a dependent name is unqualified, it is looked up from a first declaration of the function template (13.8.1 [temp.res.general]). —end note]
- If name lookup finds a non-function, that entity is considered.
- Otherwise, if name lookup finds a set of block-scope declarations (including using-declarations), that set is considered.
- Otherwise, if the name appears in a class scope, the lookup set for the name, merged with any dependent using-declarations, is considered.
- Otherwise, if the parenthesized name is the postfix-expression of a dependent call, the name itself and the namespace scope is considered, not the result of name lookup.
- Otherwise, if the name is the postfix-expression in a dependent call, only the name itself is considered, not the result of name lookup.
Change in 13.8.3.1 [temp.dep.general] paragraph 2 as follows:
A dependent call is an expression, possibly formed as a non-member candidate for an operator (12.2.2.3 [over.match.oper]), of the form:postfix-expression ( expression-listopt )where the postfix-expression isana (possibly parenthesized) unqualified-id and
- any of the expressions in the expression-list is a pack expansion (13.7.4 [temp.variadic]), or
- any of the expressions or braced-init-lists in the expression-list is type-dependent (13.8.3.3 [temp.dep.expr]), or
- the unqualified-id is a template-id in which any of the template arguments depends on a template parameter.
(From submission #631.)
It is unclear whether the resolution of issue 1321 covers cases where argument-dependent lookup is not used, for example because a callable object or a block-scope extern declartion was found. There is implementation divergence (EDG accepts, others reject) for the following example:
template <typename ...T> struct Blob : T ... { using T::operator() ...; }; template <typename T> constexpr bool IsInt = false; template <> constexpr bool IsInt<int> = true; template <typename T> concept C = IsInt<T>; namespace N { constexpr auto f() { int f(int); return [](auto x) requires C<decltype(f(x))> { return true; }; } } namespace M { constexpr auto f() { short f(int); return [](auto x) requires C<decltype(f(x))> || (sizeof(x) == 4) {}; } } template <typename ...T> constexpr Blob<T ...> blobber(T ...) { return {}; } static_assert(blobber(N::f(), M::f())(0));
The wording says the example is well-formed, because the use of C in N::f subsumes the use of C in M::f, despite the fact that the use of C in M::f can never be satisfied.
Additionally, a call of the form (f)(x,y) (with a parenthesized postfix-expression) is not considered a dependent call per 13.8.3.1 [temp.dep.general] paragraph 2, leaving the issue addressed by issue 1321 open for such cases.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-10-30 12:32:51 | admin | set | messages: + msg7866 |
2024-10-30 00:00:00 | admin | create |