简体   繁体   English

初始化 std::vector<int> 里面有方括号[]; 怎么了?</int>

[英]Initializing std::vector<int> with square brackets [] inside; what is happening?

Background information about what inspired my question:关于激发我的问题的背景信息:

I learned about Designated Initializers in C, which are awesome, and allow you to initialize C arrays in C like this, which is awesome: I learned about Designated Initializers in C, which are awesome, and allow you to initialize C arrays in C like this, which is awesome:

int my_array[] = 
{
    [MY_ENUM1] = 7,
    [MY_ENUM5] = 6,
};

I tried it in C++ and it doesn't work ( see my comments under the answer linked-to above).我在 C++ 中尝试过,但它不起作用( 请参阅上面链接到的答案下的评论)。 Bummer.真可惜。 I tried it in a C++ std::vector and got behavior I don't understand.我在 C++ std::vector中进行了尝试,得到了我不明白的行为。 What is happening here?这里发生了什么?

The crux of my question:我问题的症结所在:

What are the [7] = 12 and [10] = 15 doing in my example?在我的示例中, [7] = 12[10] = 15在做什么? What is going on there?那里发生了什么? Why does that compile?为什么会编译? Why is the output the way it is?为什么 output 是这样的?

I just compiled the below code with -Wall -Wextra -Werror -Wpedantic , and it still compiles with zero warnings.我刚刚用-Wall -Wextra -Werror -Wpedantic编译了下面的代码,它仍然以零警告编译。 -Wpedantic is one I almost never use, and do not recommend , because it turns off compiler extensions, which I like to keep on. -Wpedantic是我几乎从不使用且不推荐使用的一种,因为它关闭了我喜欢继续使用的编译器扩展。 Yet, I still get no warnings with that unusual [7] = 12 syntax.然而,对于这种不寻常的[7] = 12语法,我仍然没有收到任何警告。

Update: something seems to be wrong with onlinegdb's ability to accept my compiler flags.更新:onlinegdb 接受我的编译器标志的能力似乎有问题。 With -Wpedantic I do see the warning when I run it locally :使用-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 , however, I see no warnings nor errors:但是,如果没有-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

...yet the output still doesn't follow the rules of Designated Initializers either. ...然而 output 仍然不遵循指定初始化程序的规则。 Am I in the realm of something like a compiler bug?我在 realm 之类的编译器错误中吗? I'd still like more answers and clarity.我仍然想要更多的答案和清晰度。

My g++ --version is g++ (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0 .我的g++ --versiong++ (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0

See especially my comment in the code below:尤其是我在下面代码中的评论:

Run it online: https://onlinegdb.com/FZ2YdZXJe (gcc compiler set to C++17)在线运行: 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;
}

Output: Output:

1
2
3
12
15
4

Also, I was actually expecting the output to look like this, assuming it were to act like "designated initializers" in C arrays.此外,我实际上期待 output 看起来像这样,假设它在 C arrays 中表现得像“指定初始化程序”。 Since I didn't get this output, something else I don't understand must be going on (hence this question).由于我没有得到这个 output,所以我不明白的其他事情必须发生(因此这个问题)。

1
2
3
0
0
0
0
12
0
0
15
4

Why does this "work" here?为什么这个“工作”在这里? What is happening?怎么了?

It does not, it is non standard.它没有,它是非标准的。


For a short overview, have a look at: https://www.modernescpp.com/index.php/designated-initializers .如需简要概述,请查看: https://www.modernescpp.com/index.php/designated-initializers

Especially at the paragraph: https://www.modernescpp.com/index.php/designated-initializers#h2-1-differences-between-c-and-c特别是在以下段落: https://www.modernescpp.com/index.php/designated-initializers#h2-1-differences-between-c-and-c


Have a look at the GCC page: https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html看看 GCC 页面: https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

There you can read the following:在那里您可以阅读以下内容:

This extension is not implemented in GNU C++.此扩展未在 GNU C++ 中实现。


Since you're working with std::vector , have a look at how a vector can be constructed: https://en.cppreference.com/w/cpp/container/vector/vector由于您正在使用std::vector ,请查看如何构造vectorhttps://en.cppreference.com/w/cpp/container/vector/vector

The constructor listed in no.没有列出的构造函数。 10 vector(std::initializer_list<T> init) allows the initialization like this: 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};

The documentation to initializer-list can be found here: https://en.cppreference.com/w/cpp/utility/initializer_list初始化列表的文档可以在这里找到: https://en.cppreference.com/w/cpp/utility/initializer_list


General initialization in C++: https://en.cppreference.com/w/cpp/language/initialization C++ 中的一般初始化: https://en.cppreference.com/w/cpp/language/initialization

The initialization type you're most interested in would be: Aggregate initialization您最感兴趣的初始化类型是: 聚合初始化

There, in the section Designated initializers , you will be able to read the following:在那里,在指定初始化程序部分,您将能够阅读以下内容:

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++.注意:乱序指定初始化、嵌套指定初始化、指定初始化和正则初始化混合、arrays的指定初始化在C编程语言中都支持,但在ZF6F87C9FDCF18B3C2C9Z877F中不允许。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM