【问题标题】:c++ basic array initialization from initializer listc++ 从初始化列表初始化基本数组
【发布时间】:2015-06-16 09:38:45
【问题描述】:

我是 C++ 的初学者

我认为这是一个微不足道的问题,但我没有找到答案

为什么这段代码会出错?而如果我们在一行中初始化数组 byte x[2] = {78,82} 工作正常吗?

这两种情况下x指针有什么区别?

// example: one class, two objects
#include <iostream>
using namespace std;
typedef unsigned char byte;

int main () {
    byte x[2];
    x = {78,82};
    cout << x << endl;
}

我只从 netbeans 得到这个错误

error: assigning to an array from an initializer list

【问题讨论】:

  • 不能(直接)分配 C++ 原始数组。请改用std::array。它将原始数组包装在 struct 中。
  • 也许this 会帮助你
  • 一个相似之处x在任何情况下都不是指针,它是一个数组。

标签: c++


【解决方案1】:

为什么这段代码会出错?

因为您可能不会分配给数组变量。数组不能按值传递给函数或运算符。在需要指针的上下文中使用时,它们会衰减为指向第一个元素的指针。

仅使用指向每个数组的第一个元素的指针,无法将一个数组(或初始化列表)复制到另一个数组。此类操作需要有关数组大小的信息。

有一个很好的分析为什么分配不被允许here。这是关于数组到数组的分配,但我想它也适用于初始化列表。

如果我们在一行中初始化数组字节 x[2] = {78,82} 是否正常工作?

它之所以有效,是因为您可以初始化一个数组变量(在这种情况下使用list initialization)。请记住,= 会根据它是在声明还是非声明语句中使用而做不同的事情。在声明中是初始化语法,在非声明语句中是赋值运算符。

这两种情况下x指针有什么区别?

x 不是指针,它是一个数组。唯一的区别是,在一种情况下,您初始化 x 中的对象,而在另一种情况下,您将其保持未初始化状态,然后尝试为其分配一个初始化列表,这是不可能的。

【讨论】:

    【解决方案2】:

    数组没有赋值运算符。您必须将源数组中的元素逐个复制到目标数组,例如通过标准算法std::copy 或使用标准C 函数memcpy 或为任务编写自己的循环。或者您可以使用下标运算符设置数组的各个元素。

    然而,标准允许在定义数组时将具有初始化列表的数组初始化为任何其他聚合

    byte x[] = { 78, 82 }; // valid
    x = { 78, 82 }; // compilation error
    

    还有这个说法

    cout << x << endl;
    

    没有意义,因为这个数组不是以零结尾的,这会导致未定义的行为。

    但是您可以使用具有复制赋值运算符的标准类std::array,因为它是一个类并且编译器会为它隐式生成此运算符。

    例如

    #include <iostream>
    #include <array>
    
    typedef unsigned char byte;
    
    int main() 
    {
        std::array<byte, 2> x;
        x = { { 78, 82 } };
    
        std::cout.write( reinterpret_cast<char *>( x.data() ), x.size() ) << std::endl;
    }    
    

    【讨论】: