【问题标题】:Can sizeof nested twice ever be a dependent expression?嵌套两次的 sizeof 可以是依赖表达式吗?
【发布时间】:2015-02-27 01:50:40
【问题描述】:

我注意到 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&lt;sizeof(sizeof(T))&gt; 是依赖类型,这意味着应该需要typename

C++11 标准中的以下措辞涵盖了这一点:

[temp.dep.type]/8

一个类型是依赖的,如果它是

  • 一个简单模板ID,其中模板名称是模板参数或任何模板 arguments 是依赖类型或依赖于类型或值的表达式

[temp.dep.expr]/4

以下形式的表达式从不依赖于类型(因为表达式的类型不能 依赖):

sizeof unary-expression
sizeof ( type-id )

[temp.dep.constexpr]/2

如果一元表达式或表达式是类型相关的,则以下形式的表达式是值相关的 或者 type-id 是依赖的:

sizeof unary-expression
sizeof ( type-id )

我的解释是sizeof(T) 永远不能依赖于类型,这意味着sizeof(sizeof(T)) 永远不能依赖于类型或值。

这是 gcc 中的错误吗?

【问题讨论】:

  • 哦。 GCC 还认为 sizeof n 是依赖的。 melpon.org/wandbox/permlink/BLobLBzkQXNRfDuq
  • 嗯,sizeof n 不依赖于类型,而是依赖于值。 sizeof X,其中X not 类型相关根本不相关。因此,sizeof sizeof n 必须是独立的,不是吗?
  • 有趣的是,在 gcc 4.7.2 上编译,但在 4.9.0 上失败。
  • @dyp 好点,我已经更改了示例..
  • @willj 这有什么改变? sizeof( type-id ) 仍然不依赖于类型。

标签: c++ templates language-lawyer dependent-type compiler-bug


【解决方案1】:

我正在使用 N4296 后的草稿。

typedef I<sizeof(sizeof(T))>::Type Type;
如果 nested-name-specifier I&lt;..&gt; 依赖于模板参数 [temp.res]/5,则需要

typename。那么,I&lt;..&gt; 依赖吗?

[temp.dep.type]/9 一个类型是依赖的,如果它是

  • [...]
  • (9.7) 一个 simple-template-id,其中模板名称是模板参数或任何模板参数都是依赖项 类型或类型相关值相关的表达式,或 [...]

I&lt;..&gt; 是一个simple-template-id,模板参数是一个表达式。这个表达式sizeof(sizeof(T)) 是类型相关的还是值相关的?

表达式sizeof(sizeof(T))可以分解为以下表达式:

表达形式 ================================================ T 类型标识 sizeof(T) sizeof ( type-id ) (sizeof(T)) ( 表达式 ) sizeof(sizeof(T)) sizeof 一元表达式

T 不是表达式,但我会将其留在列表中以供稍后使用。关于括号的注释:primary-expression 可以是带括号的(通用)表达式unary-expression 可以是 postfix-expression 也可以是 primary-expression,因此它也可以用括号括起来。

如果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 如果 unary-expressionexpression 是类型相关的或type-id 是依赖的:

sizeof unary-expression
sizeof ( type-id )
表达形式价值深度?类型深度? ==================================================== ====================== T type-id 否 是 sizeof(T) sizeof ( type-id ) 是 否 (sizeof(T)) ( 表达式 ) 是 否 sizeof(sizeof(T)) sizeof 一元表达式 no no

由于T类型 相关的,sizeof(T) 成为 相关的。但是,由于(sizeof(T)) 不依赖于类型sizeof(sizeof(T)) 根本不依赖。

【讨论】:

  • 括号外集的要点。出于某种原因,我很难写sizeof(expression)
猜你喜欢
  • 2015-03-15
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-20
相关资源
最近更新 更多