3

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?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • IIRC there is a defect report about this. Don't have the time to try and find it right now but I'll visit back later to see if it was found or was answered. – NathanOliver Feb 26 '20 at 22:51

1 Answers1

2

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-args in 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.

ecatmur
  • 152,476
  • 27
  • 293
  • 366