И clang 3.6, и gcc 5.0 требуют typename
в следующем примере:
template<typename T>
struct B
{
typedef int Type;
};
void f(int);
template<int n>
struct A
{
typedef typename B<decltype(f(n))>::Type Type;
};
Это описано в следующей формулировке стандарта C++11:
[temp.dep.type]/5
Имя является членом неизвестной специализации, если оно
- Квалифицированный идентификатор, в котором спецификатор вложенного имени называет зависимый тип, который не является текущим экземпляром.
[temp.dep.type]/8
Тип зависим, если он
член неизвестной специализации,
идентификатор простого шаблона, в котором либо имя шаблона является параметром шаблона, либо любой из аргументов шаблона является зависимым типом или выражением, зависящим от типа или значения.
обозначается
decltype(expression)
, где выражение зависит от типа
Это предполагает, что B<decltype(f(n))>::Type
зависит от типа, только если B<decltype(f(n))>
зависит от типа. Также, что B<decltype(f(n))>
зависит, только если f(n)
зависит от типа.
[temp.dep.expr]/1
За исключением случаев, описанных ниже, выражение зависит от типа, если любое подвыражение зависит от типа.
[temp.dep.expr]/3
Идентификационное выражение зависит от типа, если оно содержит
идентификатор, связанный поиском имени с одним или несколькими объявлениями, объявленными с зависимым типом,
идентификатор шаблона, который является зависимым,
идентификатор функции преобразования, указывающий зависимый тип, или
спецификатор вложенного имени или квалифицированный идентификатор, который называет члена неизвестной специализации;
или если он называет статический элемент данных текущего экземпляра, который имеет тип «массив неизвестной границы T» для некоторого T
Это предполагает, что f(n)
зависит от типа, только если n
зависит от типа, и что n
не зависит от типа.
Я что-то упустил, или это ошибка компилятора?
f(n)
на*new int(n)
, который не зависит от типа в соответствии с [temp.dep.expr]/3. - person willj   schedule 31.12.2014