Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why template accept a not matching parameter?

Tags:

c++

templates

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.

like image 774
qiyuewuyi2333 Avatar asked Oct 29 '25 20:10

qiyuewuyi2333


1 Answers

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:

  • Constraints of the Parameter Template (i.e., P in S) must be equally strict or less strict than the constraints of the argument templates (X, Y, Z).
  • Argument Templates cannot require more constraints than the parameter template

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

like image 171
qiyuewuyi2333 Avatar answered Oct 31 '25 12:10

qiyuewuyi2333



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!