我注意到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
如果类型是
,则类型是依赖的
- 一个simple-template-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中的错误吗?
答案 0 :(得分:7)
我正在使用N4296之后的草稿。
typedef I<sizeof(sizeof(T))>::Type Type;
如果嵌套名称说明符 typename
依赖于模板参数[temp.res] / 5,则需要 I<..>
。那么,I<..>
依赖吗?
[temp.dep.type] / 9如果类型是
,则类型是依赖的
- [...]
- (9.7) simple-template-id ,其中模板名称是模板参数或任何模板参数是依赖项 类型或表达式类型相关或依赖于值,或 [...]
I<..>
是 simple-template-id ,模板参数是表达式。此表达式sizeof(sizeof(T))
是依赖于类型还是取决于值?
表达式sizeof(sizeof(T))
可以分解为以下表达式:
expression form =============================================== T type-id sizeof(T) sizeof ( type-id ) (sizeof(T)) ( expression ) sizeof(sizeof(T)) sizeof unary-expression
T
不是表达式,但我会将其留在列表中以供日后使用。括号中的注释: primary-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如果一元表达式或表达式与类型有关,则以下形式的表达式是值依赖的或 type-id 依赖:
sizeof unary-expression sizeof ( type-id )
expression form value-dep? type-dep? ======================================================================= T type-id no yes sizeof(T) sizeof ( type-id ) yes no (sizeof(T)) ( expression ) yes no sizeof(sizeof(T)) sizeof unary-expression no no
由于T
类型 - 依赖,sizeof(T)
变为值 - 依赖。但是,由于(sizeof(T))
不是 - 依赖,sizeof(sizeof(T))
根本不依赖。