有关激发我的问题的背景信息:
我了解了 C 中的 Designated Initializers,它很棒,并且允许您像这样在 C 中初始化 C 数组,这很棒:
int my_array[] =
{
[MY_ENUM1] = 7,
[MY_ENUM5] = 6,
};
我在 C++ 中尝试过它,但它不起作用(上面链接的答案下的 see my comments)。无赖。我在 C++ std::vector
中尝试了它,但得到了我不理解的行为。这里发生了什么?
我的问题的关键:
[7] = 12
和 [10] = 15
在我的例子中做了什么?那里发生了什么?为什么要编译?为什么输出是这样?
我刚刚用 -Wall -Wextra -Werror -Wpedantic
编译了下面的代码,它仍然编译时出现零警告。 -Wpedantic
is one I almost never use, and do not recommend ,因为它关闭了编译器扩展,我喜欢继续这样做。然而,对于这种不寻常的 [7] = 12
语法,我仍然没有收到任何警告。
更新:onlinegdb 接受我的编译器标志的能力似乎有问题。使用 -Wpedantic
我在本地运行它时确实看到了警告:
eRCaGuy_hello_world/cpp$ g++ -Wall -Wextra -Werror -Wpedantic -O3 -std=c++17 vector_with_square_brackets.cpp -o bin/a && bin/a
vector_with_square_brackets.cpp:19:5: error: ISO C++ does not allow C99 designated initializers [-Werror=pedantic]
[7] = 12, // Why does this "work" here? What is happening?
^
vector_with_square_brackets.cpp:20:5: error: ISO C++ does not allow C99 designated initializers [-Werror=pedantic]
[10] = 15,
^
cc1plus: all warnings being treated as errors
WithOUT -Wpedantic
,但是,我没有看到任何警告或错误:
eRCaGuy_hello_world/cpp$ g++ -Wall -Wextra -Werror -O3 -std=c++17 vector_with_square_brackets.cpp -o bin/a && bin/a
1
2
3
12
15
4
...但是输出仍然不遵循指定初始化器的规则。 我是否处于编译器错误之类的领域?我仍然希望获得更多答案和清晰度。
我的g++ --version
是g++ (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0
。
请参阅我在下面代码中的注释:
在线运行:https://onlinegdb.com/FZ2YdZXJe(gcc编译器设置为C++17)
#include <iostream>
#include <vector>
std::vector<int> v =
{
1,
2,
3,
[7] = 12, // Why does this "work" here? What is happening?
[10] = 15,
4,
};
int main()
{
for (int i : v)
{
std::cout << i << "\n";
}
printf("\n");
return 0;
}
输出:
1
2
3
12
15
4
此外,我实际上希望输出看起来像这样,假设它在 C 数组中的作用类似于“指定的初始值设定项”。由于我没有得到这个输出,所以我不明白的其他事情必须继续(因此这个问题)。
1
2
3
0
0
0
0
12
0
0
15
4
更新:它似乎是一个 GCC 编译器错误
...它存在于版本 8.4(我正在使用的版本)中,但已被版本 9.1 修复。请参阅此答案下方的评论:
I would say, this was a general issue with previous versions of the compilers, because GCC 8.4 does compile it: https://godbolt.org/z/xqYq6jeb8. Since version 9.1, errors starts to occur. – Erdal Küçük
最佳答案
快速回答
Why does this "work" here? What is happening?
它不是,它是非标准的。 这是一个编译器错误。 GCC 8.4 版(OP 的版本)编译时没有任何警告和/或错误(参见:https://godbolt.org/z/xqYq6jeb8)。 9.1版本之后开始出现错误。
详情
有关简短概述,请查看:https://www.modernescpp.com/index.php/designated-initializers .
特别是在段落:https://www.modernescpp.com/index.php/designated-initializers#h2-1-differences-between-c-and-c
查看 GCC 页面:https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
在那里你可以阅读以下内容:
This extension is not implemented in GNU C++.
由于您正在使用 std::vector
, 看看如何 vector
可以构建:https://en.cppreference.com/w/cpp/container/vector/vector
第 1 号中列出的构造函数。 10 vector(std::initializer_list<T> init)
允许像这样初始化:
//Constructs the container with the contents of the initializer list init.
std::vector<int> v = {1, 2, 4};
初始化列表的文档可以在这里找到:https://en.cppreference.com/w/cpp/utility/initializer_list
C++ 中的一般初始化:https://en.cppreference.com/w/cpp/language/initialization
您最感兴趣的初始化类型是:Aggregate initialization
在 Designated initializers 部分,您将能够阅读以下内容:
Note: out-of-order designated initialization, nested designated initialization, mixing of designated initializers and regular initializers, and designated initialization of arrays are all supported in the C programming language, but are not allowed in C++.
经过一些讨论,我们发现,问题必须与编译器(版本)的不同实现有关。
由于标准,例如编译器 GCC 指出,C 语言支持指定的初始值设定项,但 C++ 语言不支持指定的初始值设定项,GCC 8.4 版(OP 的版本)编译时没有任何警告和/或错误(参见:https://godbolt.org/z/xqYq6jeb8)。 9.1版本之后开始出现错误。
关于c++ - 用方括号 [] 初始化 std::vector<int> ;怎么了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70873232/