Consider the following demonstrative program.
#include <iostream>
template <class T1, class T2 = T1>
struct A
{
};
template <template <class> class T>
void f( const T<int> & )
{
std::cout << "f( const T<int> & )\n";
}
int main()
{
A<int> a;
f( a );
f<A>( a );
}
The compiler gcc HEAD 10.0.1 20200 compiles the program successfully and the program output is
f( const T<int> & )
f( const T<int> & )
The compiler clang HEAD 11.0.0 compiles neither the first call of the function f nor the second call of the function f. It issues an error message similar to that
prog.cc:25:5: error: no matching function for call to 'f'
f( a );
^
prog.cc:9:6: note: candidate template ignored: substitution failure: template template argument has different template parameters than its corresponding template template parameter
void f( const T<int> & )
^
1 error generated.
The compiler Visual C++ 2019 does not compile the first function call
f( a );
but compiles successfully the second function call
f<A>( a );
So a question arises which compiler behaves according to the C++ 17 (or maybe C++ 20) Standard?
This is CWG 150, which was resolved by DR P0522, which is in C++17.
Note that g++ rejects the program (both calls to f) in C++14 mode (-std=c++14, etc).
Clang accepts your program only in a non-default mode, enabled with the flag -frelaxed-template-template-args, per the following rationale:
Despite being the resolution to a Defect Report, this feature is disabled by default in all language versions, and can be enabled explicitly with the flag
-frelaxed-template-template-argsin Clang 4 onwards. The change to the standard lacks a corresponding change for template partial ordering, resulting in ambiguity errors for reasonable and previously-valid code. This issue is expected to be rectified soon.
I'm not sure exactly which ambiguity errors Clang are concerned about, but a plausible example would be this recent question.
As for MSVC, it rejects the second call to f in C++14 mode (-std:c++14), accepting it in C++17 mode (-std:c++17), demonstrating that they consider the second call to be covered by P0522 as per the compliance table; it's unfortunate that they don't appear to have considered the case of the first call where the template template argument is deduced from a function argument, which is equivalent to the first case in CWG 150. I've filed an issue at Developer Community.
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