Consider an alias template like the A
in the code below. Now let B
be an alias template of A
.
In the code below these class templates are used as template arguments for a struct C
which is only specialized for one typename (A
). clang -std=c++11
exists with error: implicit instantiation of undefined template 'C<B>'
indicating that another specialization for B
is needed.
template<int N>
using A = int;
template<int N>
using B = A<N>;
template<template<int> class I>
struct C;
template<>
struct C<A> {};
int main() {
C<A> c;
C<B> d; // clang error: implicit instantiation
}
Why (if even) is it that - despite not allowing specializations of aliases - A
and B
are treated as different class templates? Is there a workaround allowing me to rename a lengthy template without incurring this problem?
This is CWG issue #1286, which deals with this example:
template<template<class> class TT> struct X { }; template<class> struct Y { }; template<class T> using Z = Y<T>; X<Y> y; X<Z> z;
questioning whether or not y
and z
have the same type.
Basically, according to the Standard, clang is correct in rejecting the code. All [temp.alias] tells us is:
When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template.
So while A<X>
is equivalent to B<X>
(for all X
!), there is no wording that A
is equivalent to B
. But on some level that doesn't really make any sense since B
and A
should be equivalent. There is a proposed resolution that would make them so, but it has not yet been approved.
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