Может ли sizeof, вложенный дважды, быть зависимым выражением?

Я заметил, что gcc 5.0 отклоняет следующий код, в то время как clang 3.6 принимает его.

template<int n>
struct I
{
typedef int Type;
};

template<typename T>
struct A
{
typedef I<sizeof(sizeof(T))>::Type Type;
};

Два компилятора, кажется, отличаются sizeof(sizeof(T)) является зависимым от типа или значения зависимым выражением. Если выражение было зависимым, то из этого следует, что I<sizeof(sizeof(T))> является зависимым типом, что означает, что typename должно быть обязательно

На это распространяется следующая формулировка в стандарте C ++ 11:

[Temp.dep.type] / 8

Тип зависит, если он

  • простой идентификатор шаблона, в котором имя шаблона является параметром шаблона или любой из шаблона
    Аргументы являются зависимым типом или выражением, которое зависит от типа или значения
[Temp.dep.expr] / 4

Выражения следующих форм никогда не зависят от типа (потому что тип выражения не может быть
зависимая):

sizeof unary-expression
sizeof ( type-id )
[Temp.dep.constexpr] / 2

Выражения следующей формы зависят от значения, если унарное выражение или выражение зависит от типа
или идентификатор типа зависит:

sizeof unary-expression
sizeof ( type-id )

Моя интерпретация такова, что sizeof(T) никогда не может зависеть от типа, то есть sizeof(sizeof(T)) никогда не может зависеть от типа или значения.

Это ошибка в GCC?

16

Решение

Я использую черновик после N4296.

typedef I<sizeof(sizeof(T))>::Type Type;

typename требуется, если вложенное имя спецификатор I<..> зависит от параметра шаблона [temp.res] / 5. Итак, это I<..> зависит?

[temp.dep.type] / 9 Тип зависит, если он

  • […]
  • (9.7) простой шаблон-идентификатор в котором либо имя шаблона является параметром шаблона, либо любой из аргументов шаблона является зависимым
    тип или выражение, которое зависящий от типа или же Значение-зависимого, или же
    […]

I<..> это простой шаблон-идентификатор, Аргумент шаблона является выражением. Это выражение sizeof(sizeof(T)) зависит от типа или значения?

Выражение sizeof(sizeof(T)) можно разбить на следующие выражения:

форма выражения
===============================================
T      тип-идентификатор
sizeof (T) sizeof ( тип-идентификатор )
(sizeof (T)) ( выражение )
sizeof (sizeof (T)) Унарное выражение

T это не выражение, но я оставлю его в списке на потом. Примечание в скобках: A первичное выражение может быть заключен в скобки (общий) выражение. Унарное выражение может быть постфикс-выражение который может быть первичное выражение, следовательно, это также может быть заключено в скобки.

Выражение в скобках (X) зависит, если X зависит:

[temp.dep.expr] / 1 За исключением случаев, описанных ниже, выражение зависит от типа, если любое подвыражение зависит от типа.

[temp.dep.constexpr] / 1 За исключением случаев, описанных ниже, константное выражение зависит от значения, если любое подвыражение зависит от значения.

В общем, sizeof выражения никогда не тип-зависимый, потому что они всегда производят значение типа std::size_t:

[temp.dep.expr] / 4 Выражения следующих форм никогда не зависят от типа (потому что тип выражения не может быть зависимым):

[...]
sizeof unary-expression
sizeof ( type-id )

Однако значение, которое они дают, может зависеть от параметра шаблона:

[temp.dep.constexpr] / 2 Выражения следующего вида зависят от стоимости, если Унарное выражение или же выражение зависит от типа или тип-идентификатор зависит:

sizeof unary-expression
sizeof ( type-id )
Форма выражения value-dep? тип-DEP?
================================================== =====================
T      тип-идентификатор                    нет да
sizeof (T) sizeof ( тип-идентификатор )         да нет
(sizeof (T)) ( выражение )             да нет
sizeof (sizeof (T)) Унарное выражение    нет нет

поскольку T является тип-зависимая, sizeof(T) становится значение-зависимый. Тем не менее, так как (sizeof(T)) является не тип-зависимая, sizeof(sizeof(T)) не зависит вообще.

7

Другие решения


По вопросам рекламы [email protected]