为什么我可以在不使用赋值运算符的情况下使用列表初始化普通数组
Why can i initialize a plain array using a list without using assignment operator
我在某人的代码中发现,我们可以使用列表在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++数组?你能给出这个语法的任何参考吗?我不知道在哪里可以找到它。
为什么我们可以在C++中做到这一点,而在 C 中却不能这样做?
C++和C是不同的语言。在 C 语言中,=
是必需的。在C++(自 C++11 起(,它是可选的。
在C++中,它称为聚合初始化,其语法如下:
T object = {arg1, arg2, ...};
T object {arg1, arg2, ...}; // (since C++11)
有关更多详细信息:请参阅 C++ 规范中的第 8.5.1 节聚合 [dcl.init.aggr]。
在 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中没有这样的细分。这没有意义,因为在它背后没有 C 中初始化的特殊语义。
在没有特殊语义的情况下引入不同形式的初始化只会让用户感到困惑。
相关文章:
- 复制列表初始化的隐式转换的等级是多少
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- C++11 中的混合列表初始化
- 我可以列表初始化 std::vector 并完美转发元素吗?
- 无法在声明时使用初始值设定项列表初始化常量字符*/字符串数组的向量
- C++20 从括号中的值列表初始化聚合,不支持内部数组
- 如何在向量列表初始化时避免对象复制以及如何延长临时的生存期
- 默认参数和空列表初始化
- 如何在列表初始化中放置额外的语句?
- C++列表初始化允许多个用户定义的转换
- 列表初始化是否将原子初始化为零
- 使用可变模板列表初始化数组,并放置new
- 使用整数初始化列表初始化长双精度的向量
- 直接列表初始化的自动规则
- 使用初始化列表初始化unique_ptr的容器,继续
- 如何修复"非聚合无法使用初始值设定项列表初始化" <map>
- 直接列表初始化和复制列表初始化之间的差异
- 为什么我可以在不使用赋值运算符的情况下使用列表初始化普通数组
- C++ - 使用类中的初始值设定项列表初始化动态集