Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[temp.names] How transient are template template parameter constraints? #658

Open
hubert-reinterpretcast opened this issue Dec 23, 2024 · 0 comments

Comments

@hubert-reinterpretcast
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant