Идентификация псевдонимов шаблонов
Рассмотрим набор шаблонных псевдонимов:
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>;
Являются ли id_foo
, id_bar
, id_buz
одинаковыми или разными типами? Существуют ли foo
, bar
, buz
одинаковые или разные шаблоны?
У разных компиляторов есть разные мнения по этому поводу.
В частности,
- MSVC 2015 и clang 3.5 считают, что все они разные.
- gcc 4.9 рассматривает
buz
так же, как foo
Стандартный С++ 11 в главе 14.5.7 "Шаблоны псевдонимов" неясно.
Ответы
Ответ 1
Как TC указал в свой комментарий на вопрос, это известное отверстие стандарта.
Текущая редакция 14.5.7 [temp.alias] касается только эквивалентности специализации шаблона псевдонима с идентификатором типа после подстановки. Должна быть добавлена формулировка, указывающая, при каких обстоятельствах сам шаблон псевдонима эквивалентен шаблону класса.
То есть: любая специализация foo
, bar
и buz
будет представлять один и тот же тип. Но нет гарантии, что при использовании в качестве параметра шаблона foo
, bar
и buz
взаимозаменяемы.