【发布时间】:2013-10-01 16:59:28
【问题描述】:
由于int() 和int{} 是值等于0 的constant 表达式,我认为它们是等价且可互换的,因此编译器必须平等对待它们。例如,
int a[0]; //error: zero-sized array not allowed in ISO C++
int b[int()]; //error: zero-sized array not allowed in ISO C++
int c[int{}]; //error: zero-sized array not allowed in ISO C++
但似乎在某些极端情况下它们是不可互换的。
-
初始化指针时:
int *p = 0; //ok int *q = int(); //error - by clang only int *r = int{}; //error - by gcc and clang both查看GCC 和Clang 消息。我怀疑这是两个编译器中的一个错误,因为我希望它们在这种情况下可以互换,但我很高兴被证明是错误的。 :-)
-
当传递给类模板时:
template<int N> struct X{}; X<0> x1; //ok X<int{}> x2; //ok (same as X<0>) X<int()> x3; //error我发现
X<int()>的语法非常熟悉,因为我以前见过(并且可能使用过)类似的语法,例如在std::function<int()>中,模板参数int()预计为函数类型(而不是0)不接受任何参数并返回int。但我想知道在这种情况下int()被视为函数 type 的规范部分,并不等同于始终为0的int{}。
【问题讨论】:
-
所以这基本上是一个“grep the standard for me”的问题,对吧?
-
我也喜欢。这是一个很好的问题——我的印象是标准并不清楚(但我还在研究它)。
-
@SteveJessop 你认为最棘手的解析是否适用于这里的任何情况?我没看到,除了
X<int()>。即便如此,我认为编译器首先找到X,因此知道它不是在寻找类型。 -
关于
X<int()>: 14.3 [temp.arg] "在 template-argument 中,type-id 之间的歧义 并且一个 expression 被解析为一个 type-id,而不管对应的 template-parameter 的形式。”跨度> -
@SteveJessop 是的。那个对我来说似乎也有问题。 C++ 通常会尽量避免需要语义信息来驱动解析。 (它并不总是成功。)在
X<int()>的情况下,语法上下文 允许类型声明,因此除非标准要求编译器获取语义信息(模板参数的事实不是类型参数),它是一个类型声明(也是最令人头疼的解析的另一个实例。
标签: c++ gcc clang zero compile-time-constant