Description
Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong
Reference (section label): temp.names
Link to reflector thread (if any): N/A
Issue description
https://wg21.link/temp.names#8 specifies that when
all template-arguments in the simple-template-id are non-dependent ([temp.dep.temp]), the associated constraints ([temp.constr.decl]) of the constrained template shall be satisfied
where the "constrained template" may be a template template parameter.
Note: GCC and Clang fail to implement this even for straightforward cases.
It is unclear how this interacts with instantiation or substitution. In particular, https://wg21.link/temp.arg.template#3 allows for the template template parameter to be more constrained than the argument provided; however, once the template template parameter is replaced by the corresponding argument, the constraints of the template template parameter seemingly disappear into the void.
Is the following ill-formed because of non-satisfaction of C<int>
?
template <typename T>
concept C = false;
template <typename> struct Q;
template <template <C> class TT>
struct A {
template <typename T> void f(TT<T> *) {}
};
template void A<Q>::f(Q<int> *);
Implementations appear to accept the above: https://godbolt.org/z/68hE87TdY
In the opposite direction, given the special case in https://wg21.link/temp.arg.template#3 to allow P
to be unconstrained, also consider:
template <typename T>
concept C = false;
template <typename> struct Q;
template <template <typename> class TT, typename T>
using Alias = TT<T>;
template <template <C> class TT>
struct A {
Alias<TT, int> *p;
};
A<Q> a;
With GCC and Clang being known to be defective, the other implementations appear to use the constraints of TT
from A
despite the emanation of the simple-template-id from Alias
.
Suggested resolution
The transient nature of the constraints on template template parameters are unavoidable if we allow constrained templates as arguments for unconstrained template template parameters: for example, the constraints of a template template parameter is not transmitted when it is used as an argument for an unconstrained template template parameter of a class template.
The question is whether the constraints from the template template parameter should be checked for "usages" (perhaps via substitution into an alias template) of the template template parameter within its scope once the arguments are known.