10

Let's consider a set of template aliases:

template<class T> using foo = T*;
template<class T> using bar = T*;
template<class T> using buz = foo<T>;

template< template<class>class TT > struct id {};

using id_foo = id<foo>;
using id_bar = id<bar>;
using id_buz = id<buz>;

Are id_foo, id_bar, id_buz same or different types? Are foo, bar, buz same or different templates?

Various compilers have different opinions on that. Particularly,

  • MSVC 2015 and clang 3.5 treat they all are different
  • gcc 4.9 treats buz is same as foo

Standard C++11 in the chapter 14.5.7 "Alias templates" is unclear.

Constructor
  • 7,273
  • 2
  • 24
  • 66
Nickolay Merkin
  • 2,673
  • 1
  • 16
  • 14
  • 2
    [cppreference](http://en.cppreference.com/w/cpp/language/type_alias)'s explanation seems to imply that yes, they are the same IMO. Edit: Relevant snippet: `An alias template is a template which, when specialized, is equivalent to the result of substituting the template arguments of the alias template for the template parameters in the type-id` – AndyG Mar 16 '15 at 15:31
  • 5
    http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1286 – T.C. Mar 16 '15 at 16:03
  • Answers to the following questions may be helpful: [_Using a template alias instead of a template within a template_](http://stackoverflow.com/q/17392621/3043539) and [_Strange behaviour of is_same_template on template aliases_](http://stackoverflow.com/q/22892052/3043539). – Constructor Mar 17 '15 at 05:27
  • 2
    @T.C. Other than it being only a link, how is that not an answer? :p – Yakk - Adam Nevraumont Mar 17 '15 at 13:30

1 Answers1

1

As T.C. pointed out in his comment to the question, this is a known hole of the standard.

The current wording of 14.5.7 [temp.alias] deals only with the equivalence of a specialization of an alias template with the type-id after substitution. Wording needs to be added specifying under what circumstances an alias template itself is equivalent to a class template.

That is: any specialization of foo, bar and buz will represent the same type. But there is no guarantee that, when used as a template parameter, foo, bar and buz are interchangeable.

Community
  • 1
  • 1
Paolo M
  • 12,403
  • 6
  • 52
  • 73