为什么我可以使用列表初始化普通数组而不使用赋值运算符

时间:2017-06-18 13:11:32

标签: c++ c arrays initialization operators

我在某人的代码中发现,我们可以使用列表在C ++中初始化普通c样式数组而不实际使用赋值运算符。代码是这样的:

int a[4]{1, 2, 3, 4};
for (int i =0; i < 4; i++){
    cout << a[i] << '\n';
}

上面的代码运行正常。上面的初始化就像我们在C ++中初始化int的向量一样。我尝试在C中使用它。但是不允许这样做。

为什么我们可以在C ++中执行此操作但不在C中执行此操作?从什么时候开始我们可以将这种初始化语法用于普通的C ++数组?你能提供这种语法的参考吗?我不知道在哪里找到它。

3 个答案:

答案 0 :(得分:2)

  

为什么我们可以在C ++中执行此操作但不在C中执行此操作?

C ++和C是不同的语言。在C中,=是必需的。在C ++中(从C ++ 11开始),它是可选的。

在C ++中,它被称为aggregate initialization,它具有以下语法:

T object = {arg1, arg2, ...};
T object {arg1, arg2, ...};     // (since C++11)

有关详细信息,请参阅C ++规范中的 8.5.1聚合[dcl.init.aggr] 部分。

答案 1 :(得分:1)

在C中,初始化修复了一个表单

init-declarator:
    declarator
    declarator = initializer 
              ^^^

在C ++中,有各种形式的初始化具有不同的语义。

在C ++中,初始化在初始化中细分为复制初始化语义和直接初始化语义。

例如,非聚合类型A

的这些初始化
A a = { 10 }; // copy-initialization

A a { 10 }; // direct-initialization

可以产生不同的结果,具体取决于相应的构造函数是显式的还是非显式的。

考虑以下计划

int main()
{
    struct A
    {
        explicit A(int x) : x(x) {}

        int x;
    };

    A a1 { 1 };
    // A a2 = { 1 }; - compilation error
}

此外,在C ++中还有初始化列表和初始化列表构造函数。

以下列方式修改上一个示范程序

#include <iostream>
#include <initializer_list>
#include <numeric>

int main()
{
    struct A
    {
        explicit A(int x) : x(x) 
        {
            std::wcout << "A::A( int )" << std::endl;
        }
        explicit A(std::initializer_list<int> lst) :
            x(std::accumulate(lst.begin(), lst.end(), 0)) 
        {
            std::wcout << "A::A( std::ininitializer_list<int> )" << std::endl;
        }
        int x;
    };

    A a { 1 };
}

并查看其输出。

在C中没有这样的细分。它没有意义,因为它背后没有特殊的初始化语义。

在没有特殊语义的情况下引入不同形式的初始化只会让用户感到困惑。

答案 2 :(得分:-3)

这是相对较新的c ++ - 11标准的一部分。之前没有它。 pre-c11 c ++在那里给出了一条错误信息。好吧,'c'是一个更老的标准:)

$ g++ a.cpp
a.cpp:3:16: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
  static int a[4]{1,2,3,4};