An injected-class-name as a template argument is weird: it can be used as an argument for both a template template parameter and a type template parameter. For example:
template<typename U>
class A {
template<typename T> using X = T::template apply<A>;
template<typename T> using Y = T::template apply<::A>;
template<typename T> using Z = T::template apply<A<U>>;
template<typename T> X<T> f() {}
template<typename T> Y<T> f() {}
template<typename T> Z<T> f() {}
};
The first f accepts types T that have a member template that takes either a type or a template.
The second f accepts types T that have a member template that takes a template.
The third f accepts types T that have a member template that takes a type.
These are three different constraints, so we need three different manglings, but we seem to only have two.
For now, GCC and Clang at least both reject -- Clang thinks the third f redeclares the first, and GCC says they're different but can't be overloaded. EDG accepts the overloads, but rejects a call to the first f with an apply that takes a template. EDG mangles the first and third overloads the same, despite considering them to be different.
An injected-class-name as a template argument is weird: it can be used as an argument for both a template template parameter and a type template parameter. For example:
The first
f
accepts typesT
that have a member template that takes either a type or a template. The secondf
accepts typesT
that have a member template that takes a template. The thirdf
accepts typesT
that have a member template that takes a type.These are three different constraints, so we need three different manglings, but we seem to only have two.
For now, GCC and Clang at least both reject -- Clang thinks the third
f
redeclares the first, and GCC says they're different but can't be overloaded. EDG accepts the overloads, but rejects a call to the firstf
with anapply
that takes a template. EDG mangles the first and third overloads the same, despite considering them to be different.