Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template template parameter deduction: three different compilers three different behaviors

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?

like image 677
Vlad from Moscow Avatar asked Jan 25 '26 23:01

Vlad from Moscow


1 Answers

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.

like image 155
ecatmur Avatar answered Jan 27 '26 16:01

ecatmur



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!