Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

alias of class template

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?

like image 520
Lmis Avatar asked Sep 27 '22 16:09

Lmis


1 Answers

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.

like image 181
Barry Avatar answered Sep 29 '22 19:09

Barry