使用方括号 [] 初始化 std::vector ;怎么了?

2023-12-11

关于激发我的问题的背景信息:

我了解了 C 中的指定初始值设定项(请参阅here和这里:https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html),这太棒了,并且允许您像这样在 C 中初始化 C 数组,这太棒了:

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

我在 C++ 中尝试过,但不起作用(看我的评论根据上面链接的答案)。真糟糕。我在 C++ 中尝试过std::vector并得到了我不理解的行为。这里发生了什么?

我的问题的关键是:

什么是[7] = 12 and [10] = 15在我的例子中做什么?那里发生了什么事?为什么会这样编译?为什么输出是这样的?

我刚刚编译了下面的代码-Wall -Wextra -Werror -Wpedantic,并且它仍然以零警告进行编译。-Wpedantic是我几乎从未使用过的,也不推荐,因为它关闭了编译器扩展,我喜欢保留它。然而,我仍然没有收到关于这种不寻常的警告[7] = 12 syntax.

更新:onlinegdb 接受我的编译器标志的能力似乎有问题。和-Wpedantic当我运行它时我确实看到了警告locally:

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

...但是输出仍然不遵循指定初始值设定项的规则。我是否遇到了编译器错误之类的问题?我仍然想要更多的答案和清晰度。

My g++ --version is 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;
}

Output:

1
2
3
12
15
4

另外,我实际上期望输出看起来像这样,假设它的行为就像 C 数组中的“指定初始值设定项”。由于我没有得到这个输出,所以一定发生了其他我不明白的事情(因此这个问题)。

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

更新:这似乎是一个 GCC 编译器错误

...它存在于版本 8.4(我正在使用的版本)中,但已被版本 9.1 修复。请参阅此答案下面的评论:

我想说,这是以前版本编译器的普遍问题,因为 GCC 8.4 确实编译了它:https://godbolt.org/z/xqYq6jeb8。从9.1版本开始,错误开始出现。 – 埃尔达尔·库楚克


快速回答

为什么这在这里“起作用”?怎么了?

事实并非如此,这是非标准的。这是一个编译器错误。GCC 版本 8.4(OP 的版本)编译时没有任何警告和/或错误(请参阅:https://godbolt.org/z/xqYq6jeb8)。 9.1版本之后,就会开始出现错误。

Details

有关简短概述,请查看:https://www.modernescpp.com/index.php/designated-initializers.

尤其是这段:https://www.modernnescpp.com/index.php/designated-initializers#h2-1-differences- Between-c-and-c


看一下 GCC 页面:https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

您可以在那里阅读以下内容:

此扩展未在 GNU C++ 中实现。


既然你正在与std::vector,看看如何vector可以构造:https://en.cppreference.com/w/cpp/container/vector/vector

编号中列出的构造函数。 10vector(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

您最感兴趣的初始化类型是:聚合初始化

在那里,在该部分指定的初始化器,您将能够阅读以下内容:

注意:乱序指定初始化、嵌套指定初始化、指定初始化器和常规初始化器混合以及数组指定初始化在 C 编程语言中都支持,但在 C++ 中不允许。


经过一番讨论,我们发现这些问题与编译器(版本)的不同实现有关。

由于标准和例如编译器 GCC 声明,C 语言支持指定的初始值设定项,但 C++ 语言不支持,GCC 版本 8.4(OP 的版本)仍然编译时没有任何警告和/或错误(请参阅:https://godbolt.org/z/xqYq6jeb8)。 9.1版本之后,就会开始出现错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用方括号 [] 初始化 std::vector ;怎么了? 的相关文章

随机推荐

  • Android 动态创建按钮并填充布局

    我正在动态创建一个按钮 按钮的数量取决于数组列表的大小 问题是 创建按钮后 我将使用 addview 方法添加到布局中 问题是我使用线性布局 因为默认情况下线性布局的方向是水平的 因此按钮将水平填充布局 因此 有些按钮是不可见的 我想要实现
  • 通过代理重定向 Angular2 http 请求

    我正在使用创建 Angular2 应用程序角度 cli引导程序和使用webpack dev server用于调试目的 对于某些类型的 http 请求 我想使用 webpack dev server 将它们重定向到另一个后端代理支持 为此我创
  • 在函数内使用 jags.parallel (R 语言 get(name, envir = envir) 中的错误:未找到对象 'y')

    从命令行或脚本使用 jags parallel 效果很好 我可以运行这个修改后的示例http www inside r org packages cran R2jags docs jags正好 An example model file i
  • Mongo Json 架构验证器 AnyOf 不起作用

    我创建了一个具有以下验证的集合 jsonSchema bsonType object additionalProperties false properties id bsonType objectId test bsonType stri
  • 如何从 ASP.NET 后台代码访问 HTML 表单输入

    我有一个基本的 HTML 表单 可以插入到服务器端div基于数据库中存在多少记录的标记 这个 HTML 表单效果很好 一切看起来都很好 但在我的操作页面上 我似乎无法从后面的代码访问输入元素 我尝试过使用Request范围 但我对这种方法一
  • linux下删除带反斜杠的文件

    我不小心创建了一个名称是反斜杠的文件 gt ls l total 0 rw rw 1 user group 0 Jul 3 21 34 我该如何删除它 为了将参数中的反斜杠传递给命令 您需要 引用 或 转义 它 您可以通过用单引号括起来来实
  • 追加到上一行以进行匹配

    我可以用吗sed or awk如果找到匹配项 则追加到上一行 我有一个格式如下的文件 INT32 FSHL const TP Buffer INT32 FSHL lm const TP Buffer WORD32 ugo 0 我想做的是扫描
  • Scapy 和 tcpreplay:绕过临时文件以提高性能

    Scapy 有一个sendpfast使用 tcpreplay 发送数据包的函数 但是 该函数首先创建一个临时 pcap 文件 然后对其调用 tcpreplay 这增加了太多的延迟 有没有办法绕过它并直接将数据发送到 tcpreplay 我知
  • Java 中的资源、URI、URL、路径和文件有什么区别?

    我现在正在查看一段 Java 代码 它采用字符串形式的路径并使用URL resource ClassLoader getSystemClassLoader getResource pathAsString 然后调用String path r
  • EL 条件方法表达式

    我想在 EL 中声明一个条件方法表达式 如下所示
  • Lisp 追加无法正常工作

    你好 我正在尝试将一个简单的元素附加到 Lisp 列表中 append queue1 pop stack1 我认为上面的代码会将 stack1 的第一个元素附加到queue1 做queue1需要非零吗 谢谢 Append returns连接
  • 为什么可变结构是“邪恶的”?

    在关于 SO 的讨论之后 我已经多次阅读了可变结构是 邪恶的 的评论 就像在这个问题的答案中一样 question C 中的可变性和结构的实际问题是什么 结构是值类型 这意味着它们在传递时会被复制 因此 如果您更改副本 您只会更改该副本 而
  • 如果导入 ipdb,python multiprocessing 进程会被 http 请求杀死

    看起来只是简单的导入ipdb当发出一个封装在 a 中的 http 请求时multiprocessing Process实例导致程序退出 没有错误或消息 以下脚本的行为非常奇怪 from multiprocessing import Proc
  • Python:如何解决问题:Django 中的“格式错误的十六进制 UUID 字符串”

    我创建了 post 模型 其中包含 post id 作为主键字段 当我尝试创建帖子时 出现错误 十六进制 UUID 字符串格式错误 我将不胜感激帮助我解决这个问题 这是我的代码 模型 py class Post models Model p
  • PHP 脚本可以在没有客户端请求的情况下在服务器上定期运行吗?

    我将编写一个脚本来将文本文档解析到 MySQL 数据库中 我将使用单独的实用程序将 PDF 转换为文本 这些 PDF 文件将通过电子邮件附件提交 我想看看是否可以使用 PHP 来做到这一点 因为这是我最熟悉的服务器语言 第二个选择是 Per
  • 直流交叉滤波器不工作

    在这里使用 dc 和 cross filter js 库构建一个 grails 应用程序 但在可视化中遇到了一个极其奇怪的问题 我的可视化是 5 个条形图 它们使用 dc 和 cross filter js 库相互互连 所以 有简单的指标
  • 为什么我的 python 字典变得无序? [复制]

    这个问题在这里已经有答案了 我正在使用它来绘制多年来以某个字母开头的名称的百分比图 当绘制 和打印 我的词典 letter d 时 键是无序的 而不是像它们添加到词典中那样是连续的 有没有办法解决这个问题 我相信我正在按顺序将它们添加到字典
  • 为什么对 wp_postmeta 的引用这么慢?

    在 WordPress 中获取属性 使用 MySQL 似乎比必要的要慢 这是一个自我回答的问题 所以请继续我的回答 标准架构为wp postmeta提供较差的索引 这会导致性能问题 通过将架构更改为此 大多数对元数据的引用将会更快 CREA
  • Method.invoke 抛出 java.lang.IllegalArgumentException:参数数量错误

    public class ReflectionTest public static void main String args throws IllegalArgumentException IllegalAccessException I
  • 使用方括号 [] 初始化 std::vector ;怎么了?

    关于激发我的问题的背景信息 我了解了 C 中的指定初始值设定项 请参阅here和这里 https gcc gnu org onlinedocs gcc Designated Inits html 这太棒了 并且允许您像这样在 C 中初始化