Consider the 2 following overloads
template<typename T>
bool test() {
return true;
}
template<template<typename ...> class T>
bool test() {
return false;
}
The 1st one works for regular classes, while the 2nd one works for templates that are not instantiated. For instance:
std::cout<<test<int>()<<std::endl; <-- this yields 1
std::cout<<test<std::list>()<<std::endl; <--this yields 0
Now consider the following template function:
template<typename U>
bool templfun(){
struct A{
bool f(){
return test<A>(); // <-- this gives an error
}
};
return test<A>(); // <-- this is ok
}
In GCC it gives an error for ambiguous overload resolution, while Clang compiles.
Interestingly, the second call to test() doesn't produce errors (even in GCC).
Moreover, if I remove the template<typename U>
thing on top of templfun, gcc stops complaining.
Is this a bug with GCC or is it illegal code?
GCC is wrong; struct A
is a templated entity but clearly not a template (as it does not start with a template
keyword), so there is no ambiguity.
To confirm, we can rename the type parameter to see that G++ is attempting to use the template-template overload.
template <typename X>
bool test() {
return true;
}
template <template <typename...> class Y>
bool test() {
return false;
}
template <typename U>
bool templfun() {
struct A {
bool f() {
return test<A>(); // <-- this gives an error
}
};
return test<A>(); // <-- this is ok
}
bool run() {
return templfun<int>();
}
G++ output: (link to godbolt)
<source>:15:27: error: call of overloaded 'test<templfun() [with U = int]::A>()' is ambiguous
15 | return test<A>(); // <-- this gives an error
| ~~~~~~~^~
<source>:2:6: note: candidate: 'bool test() [with X = templfun() [with U = int]::A]'
2 | bool test() {
| ^~~~
<source>:7:6: note: candidate: 'bool test() [with Y = templfun()::A]'
7 | bool test() {
| ^~~~
Clearly "candidate: 'bool test() [with Y = templfun()::A]'
" is bogus.
Note that local types were not allowed as template arguments prior to C++11 (see C++03 § 14.3.1.2), so that could explain the complexity of the G++ implementation.
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