code source file in godbolt:
https://godbolt.org/z/1E1oEsdKW
template <typename T>
concept C1 = sizeof(T) != sizeof(int);
template <template <C1 T> class X>
struct S4
{
X<int> x;
};
template <typename T>
class Test
{
public:
T t;
};
int main()
{
S4<Test> s1;
return 0;
}
S4 expects a template template argument whose type argument is restricted by the concept C1.
But still I can instantiate S4 with X, even though X<int> should break the concept (sizeof(int) is not different from sizeof(int)).
gcc and clang compile it without errrors, while mscv complains:
error C3201: the template parameter list for class template 'Test' does not match the template parameter list for template parameter 'X'x64 msvc v19.40 VS17.10 #Executor 1
This is what I would expect, because Ts argument is constraint by the concept while Test has no such constraint.
This is about the rules of Template Template Parameters:
Parameter List of the Parameter Template: The parameter list of the called template must match the parameter list of the parameter template. Comparison of Constraints:
Example:
template<typename T> concept C = requires (T t) { t.f(); };
template<typename T> concept D = C<T> && requires (T t) { t.g(); };
template<typename T> concept E = D<T> && requires (T t){t.h();};
template<template<D> class P> struct S { };
template<C> struct X { };
template<D> struct Y { };
template<typename T> struct Z { };
S<X> s1; // OK, X have more loose constraints
S<Y> s2; // OK, Y and P have equivalent constraints
S<Z> s3;
S<E> s4; // error, E is stricter than D
int main()
{
return 0;
}
In godbolt: https://godbolt.org/z/xW33aEfzT
reference src: https://eel.is/c++draft/temp.arg.template
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With