C++ allows template arguments that refer to template classes, not instances of it. For example the function fun
below.
At the same time there is a feature by which template arguments can be omitted inside a class definition. For example in the definition of template<class T> class A
, we can say A
to imply A<T>
.
I found a case where both rules potentially can produce an ambiguity. Moreover I cannot solve the ambiguity. Here it is a MWE, in which in the definition of template<class T> class B
I need to refer to B
as a template class and not as B<T>
.
template <template<class> class Y, class T>
auto fun(){return Y<T>{};} // fun can be used with a *template* class
template<class T>
struct A{
friend void f(A a){} //A here is implicitly A<T>, ok
};
template<class T>
struct B{
friend void g(B b){
fun<A, void>(); // here A is a template class, ok
fun<B, void>(); // error: no matching function for call to 'fun' because the compiler sees B<T>, not B
} //A here is implicitly A<T>,
};
int main(){
A<void> a{};
B<void> b{};
g(b);
}
(I need to do this because the function g
is a friend function that I want to define inside the class.)
Clang 3.5 gives the error described above, and GCC 4.9.2 is ok with it. The worst part is that I cannot make additional specifications and resolve the ambiguity.
For example I tried:
fun<struct B, void>();
fun<template<class> struct B, void>();
but still get the same error.
Is there a way to tell clang (or a problematic compiler) that B
is not B<T>
but the template class B
?
(I used some C++11 syntax to simplify the example, but the problem iapplies to C++98 as well. Please correct or let me know if I am not using the right naming conventions.)