【问题标题】:Initializer syntax error does not happen anymore with std::arraystd::array 不再发生初始化程序语法错误
【发布时间】:2015-03-27 09:24:13
【问题描述】:

根据问题std::array c++11 initializer syntax error 不允许以这种方式将花括号列表分配给 std::array:

std::array<int, 10> a = {0,1,2,3,4,5,6,7,8,9};
a = {0}; // error: cannot assign to an array from a braced list

但实际上我无法再重现此错误。 我的 GCC 版本是 4.8.2。 代码如下:

#include <array>

int main() {

   std::array<int, 10> a;

    a = {1};

    return 0;
}

它编译并执行没有任何错误。

所以,问题是,我在这里做错了吗?或者是否有任何变化导致了这种行为变化?

【问题讨论】:

  • 编译器从花括号初始化器列表中创建一个临时的std::array 对象,然后将其分配给您的a 变量。
  • 是的,我很清楚。但这个问题是故意提出的,以了解实施中发生了哪些变化以及原因。
  • 没什么,只是编译器被“修复”了。 C++ 编译器是非常复杂的程序,并且作为所有重要的程序,它都包含错误。
  • GCC 4.9.2 说这是 C++11 语法,需要用-std=c++11 or -std=gnu++11编译...

标签: c++ arrays std


【解决方案1】:

表达式a = {1}; 对应于复制列表初始化的情况(10)(参见here)。所以,按照标准应该是正确的。

您遇到的问题可能与以下从 C++11 到 C++14 的更改有关:在 C++11 中,执行聚合初始化时,嵌套初始化器列表周围的大括号可能只有在语法... = {...} 已使用,但未使用 ...{...}。在 C++14 中,后者也是允许的。有关详细信息,请参阅here。现在,假设 C++11,a = {1}; 是否正确?我认为答案取决于您如何解释标准。显然,{1} 用于初始化operator= 的第二个操作数。以下是两种可能的解释,分别给出肯定答案和否定答案。

对肯定答案的解释:语法... = {...} 执行复制列表初始化,而...{...} 执行直接列表初始化。因此,标准所说的是在复制列表初始化中允许大括号省略,但在直接列表初始化中不允许。 a = {1}; 执行复制列表初始化。所以省略是可以的。

否定答案的解释:给标准一个字面解释。等号的出现是可以的,否则就不行。在a = {1}; 中,operator= 的操作数的初始化是隐含的,没有等号。所以,这是不行的。 here 声明似乎暗示了这种逐字解释。

【讨论】:

    猜你喜欢
    • 2012-03-08
    • 1970-01-01
    • 2015-10-05
    • 2012-02-10
    • 1970-01-01
    • 2013-04-22
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多