这是允许的:
int a[]{1, 2, 3};
但不是这样:
auto a = new int[]{1, 2, 3};
您必须指定边界。为什么呢?
编辑:正确的语法(不编译)是:
auto a = new (int[]){1, 2, 3};
这给出了真正的错误消息,即:
error: invalid use of array with unspecified bounds
答案 0 :(得分:9)
MSalters' answer解决了为什么在最新版本的标准中没有改变这一点的原因。在这里,我将回答同伴问题,“C ++ 11标准在哪里被禁止?”
new (int[]){1, 2, 3}
首先,我们需要注意int[]
是一种不完整的类型。
...未知大小的数组...是一个未完全定义的对象类型。 - [basic.types]§3.9¶5
最后,我们注意到new
运算符不允许指定的类型不完整:
此类型应为完整的对象类型... - [expr.new]§5.3.4¶1
当使用 braced-init-list 语法时,标准中没有任何内容可以例外。
new int[]{1, 2, 3}
int[]
使用 new-type-id 生产进行解析,该生产使用 noptr-new-declarator 生产来解析方括号:
noptr新声明符:
[表达式] attribute-specifier-seq opt
noptr-new-declarator [ constant-expression ] attribute-specifier-seq opt
请注意,表达式未标记为可选,因此此语法无法解析。
答案 1 :(得分:5)
正如Jonathan Wakely在评论中已经指出的那样,这实际上是一个封闭的问题。决议“应该在Evolution工作组中处理”实质上意味着WG21认为这本身并不是一个坏主意,但与此同时他们并不认为它是当前标准中的缺陷。这是有道理的 - 没有任何提示应该起作用的暗示,这只是类比。
答案 2 :(得分:0)
我认为这是因为编译器以串行方式读取文件,它永远不会返回,(这就是为什么你必须使用前向声明,而不是等待函数稍后声明)。我不确定这是官方的原因,但它对我来说才有意义。
这是我的解释:
行int Array[]={1,2,3};
可以按照以下方式连续处理:
启动数组:将1放在第1位,将2放在第2位,将3放在第3位,结束数组,因此:数组大小为3个整数,因此按此大小移动堆栈帧。
但是以下行:int *p=new int[]{1,2,3};
除了将元素放在内存中并检测大小外,还应该从内存分配开始。怎么能以连续的方式完成?
要允许这样的事情,你必须打破连续性原则,并从最后开始处理,然后返回调用适当的分配大小。
修改强>
回应第1条评论
我做了一些测试,在下面的代码中:
class A{
public:
A(){
err2 error;
cout<<sizeof(A)<<endl;
}
err1 error;
};
编译器似乎将内联函数保留为在类之后进行编译。
证据是无论顺序如何,在功能错误之前检测到成员错误。
所以在示例类中,我在err1 error
之前得到err2 error
,即使按时间顺序相反。
因此,我认为类是特殊的,否则课堂本身的使用非常有限。
<强> EDIT2:强>
int Array[]={sizeof(Array)};
给出错误,唯一的原因是在关闭数组后给出数组的大小。它与int Array[]={1,2};