初始化 C++ 向量的大小

2024-04-24

初始化 C++ 向量以及其他容器的大小有哪些优点(如果有)?有什么理由不只使用默认的无参数构造函数吗?

基本上,两者之间是否存在显着的性能差异

vector<Entry> phone_book;

and

vector<Entry> phone_book(1000);

这些示例来自 Bjarne Stroustrup 所著的《C++ 编程语言第三版》。如果这些容器应始终使用大小进行初始化,是否有一个好方法来确定开始时的良好大小?


有几种创建方法vector with n当您事先不知道元素的数量时,我什至会展示一些填充向量的方法。

但首先

不该做什么

std::vector<Entry> phone_book;
for (std::size_t i = 0; i < n; ++i)
{
    phone_book[i] = entry; // <-- !! Undefined Behaviour !!
}

默认构造的向量(如上例所示)创建一个空向量。访问向量范围之外的元素是未定义的行为。并且不要指望会得到一个很好的例外。未定义的行为意味着任何事情都可能发生:程序可能会崩溃,或者看起来可以工作,或者可能以一种不稳定的方式工作。请注意,使用reserve不会改变向量的实际大小,即你无法访问向量大小之外的元素,即使你为它们保留了。

现在分析一些选项

默认向量+push_back (次优)

std::vector<Entry> phone_book;
for (std::size_t i = 0; i < n; ++i)
{
    phone_book.push_back(entry);
}

这样做的缺点是当您推回元素时会发生重新分配。这意味着内存分配、元素移动(或复制,如果它们是不可移动的,或者对于 c++11 之前的版本)和内存释放(带有对象销毁)。这种情况很可能会发生不止一次n相当大。值得注意的是,它保证“摊余常数”push_back这意味着它不会在每次之后进行重新分配push_back。每次重新分配都会以几何级数增加大小。进一步阅读:std::vector 和 std::string 重新分配策略 https://stackoverflow.com/questions/21352323/stdvector-and-stdstring-reallocation-strategy

当您事先不知道尺寸并且甚至没有对尺寸的估计时,请使用此功能。

“计算 T 的默认插入实例” ctor 以及后续分配(不建议)

std::vector<Entry> phone_book(n);
for (auto& elem : phone_book)
{
    elem = entry;
}

这不会导致任何重新分配,但所有n元素将最初默认构造,然后为每次推送复制。这是一个很大的缺点,并且对性能的影响很可能是可衡量的。 (这对于基本类型不太明显)。

不要使用它,因为几乎每种情况都有更好的选择。

“计算元素的副本”ctor(受到推崇的)

std::vector<Entry> phone_book(n, entry);

这是最好的使用方法。当您在构造函数中提供所需的所有信息时,它将进行最有效的分配+赋值。这有可能产生无分支代码,如果满足以下条件,则使用矢量化指令进行赋值:Entry有一个简单的复制构造函数。

默认向量+reserve + push_back (情况推荐)

vector<Entry> phone_book;
phone_book.reserve(m);

while (some_condition)
{
     phone_book.push_back(entry);
}

// optional
phone_book.shrink_to_fit();

不会发生重新分配,并且对象只会构造一次,直到超出保留容量。更好的选择push_back can be emplace_back.

如果您有粗略的尺寸近似值,请使用此值。

储备价值没有神奇的公式。针对您的特定场景使用不同的值进行测试,以获得应用程序的最佳性能。最后你可以使用shrink_to_fit http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit.

默认向量+std::fill_n and std::back_inserter (情况推荐)

#include <algorithm>
#include <iterator>

std::vector<Entry> phone_book;

// at a later time
// phone_book could be non-empty at this time
std::fill_n(std::back_inserter(phone_book), n, entry);

如果您需要在创建向量后填充或添加元素,请使用此选项。

默认向量+std::generate_n and std::back_inserter (对于不同的entry物体)

Entry entry_generator();

std::vector<Entry> phone_book;
std::generate_n(std::back_inserter(phone_book), n, [] { return entry_generator(); });

如果每个都可以使用它entry是不同的并且从生成器获得

初始化列表(奖励)

由于这已经成为一个如此重要的答案,超出了问题所提出的范围,如果我没有提到初始化列表构造函数,我将被解雇:

std::vector<Entry> phone_book{entry0, entry1, entry2, entry3};

在大多数情况下,当您有一小部分用于填充向量的初始值时,这应该是默认的首选构造函数。


一些资源:

std::vector::vector(构造函数) https://en.cppreference.com/w/cpp/container/vector/vector

std::vector::insert https://en.cppreference.com/w/cpp/container/vector/insert

标准算法库 https://en.cppreference.com/w/cpp/algorithm (with std::generate https://en.cppreference.com/w/cpp/algorithm/generate std::generate_n https://en.cppreference.com/w/cpp/algorithm/generate_n std::fill https://en.cppreference.com/w/cpp/algorithm/fill std::fill_n https://en.cppreference.com/w/cpp/algorithm/fill_n etc.)

std::back_inserter https://en.cppreference.com/w/cpp/iterator/back_inserter

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

初始化 C++ 向量的大小 的相关文章

  • 无法使用已与其底层 RCW 分离的 COM 对象。在 oledb 中

    我收到此错误 但我不知道我做错了什么 下面的代码在backrgroundworker中 将异常详细信息复制到剪贴板 System Runtime InteropServices InvalidComObjectException 未处理 通
  • pthread_cond_timedwait() 和 pthread_cond_broadcast() 解释

    因此 我在堆栈溢出和其他资源上进行了大量搜索 但我无法理解有关上述函数的一些内容 具体来说 1 当pthread cond timedwait 因为定时器值用完而返回时 它如何自动重新获取互斥锁 互斥锁可能被锁定在其他地方 例如 在生产者
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • 如何返回 json 结果并将 unicode 字符转义为 \u1234

    我正在实现一个返回 json 结果的方法 例如 public JsonResult MethodName Guid key var result ApiHelper GetData key Data is stored in db as v
  • C# 中的递归自定义配置

    我正在尝试创建一个遵循以下递归结构的自定义配置部分
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • clang 实例化后静态成员初始化

    这样的代码可以用 GCC 编译 但 clang 3 5 失败 include
  • 从库中捕获主线程 SynchronizationContext 或 Dispatcher

    我有一个 C 库 希望能够将工作发送 发布到 主 ui 线程 如果存在 该库可供以下人员使用 一个winforms应用程序 本机应用程序 带 UI 控制台应用程序 没有 UI 在库中 我想在初始化期间捕获一些东西 Synchronizati
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 如何在 VBA 中声明接受 XlfOper (LPXLOPER) 类型参数的函数?

    我在之前的回答里发现了问题 https stackoverflow com q 19325258 159684一种无需注册即可调用 C xll 中定义的函数的方法 我之前使用 XLW 提供的注册基础结构 并且使用 XlfOper 类型在 V
  • 实体框架 4 DB 优先依赖注入?

    我更喜欢创建自己的数据库 设置索引 唯一约束等 使用 edmx 实体框架设计器 从数据库生成域模型是轻而易举的事 现在我有兴趣使用依赖注入来设置一些存储库 我查看了 StackOverflow 上的一些文章和帖子 似乎重点关注代码优先方法
  • WCF:将随机数添加到 UsernameToken

    我正在尝试连接到用 Java 编写的 Web 服务 但有些东西我无法弄清楚 使用 WCF 和 customBinding 几乎一切似乎都很好 除了 SOAP 消息的一部分 因为它缺少 Nonce 和 Created 部分节点 显然我错过了一
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • ASP.NET MVC 6 (ASP.NET 5) 中的 Application_PreSendRequestHeaders 和 Application_BeginRequest

    如何在 ASP NET 5 MVC6 中使用这些方法 在 MVC5 中 我在 Global asax 中使用了它 现在呢 也许是入门班 protected void Application PreSendRequestHeaders obj
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐

  • 微软动态 - Web API

    我正在尝试通过 Web API 在 Dynamics 365 实例中创建一个新的 事件 案例 在我的http请求中 我不知道哪个字段是必填的 我尝试仅添加标题 主题和客户 但返回 Http 400 错误 我正在使用 Postman 尝试我的
  • 为什么 console.dir('') 打印“无属性”?

    我的印象是字符串具有属性 例如match 为什么console dir 声称 没有属性 至少在 Google Chrome 中 这是因为 是一个字符串文字 而不是一个实例String 班级 由于属性如match宣布于String proto
  • 双击 Selenium 的 javascript 执行

    有一种方法可以通过执行 javascript 来单击元素 如下所示 JavascriptExecutor driver executeScript arguments 0 click element 我想通过执行 JavaScript 来双
  • 允许在 Google 计算引擎 (GCE) 中使用 WebSocket

    我正在使用计算引擎 GCE 通过 Socket IO Node js 运行我的套接字服务器 它仅适用于轮询 当我尝试使用网络客户端时 我收到以下错误代码 WebSocket connection to ws myapp socket app
  • Swift:Switch 语句失败行为

    目前我有这个 let somePoint 1 0 switch somePoint case 0 0 print origin does not print fallthrough case 0 print y axis prints y
  • 如何将路径图像用户存储到数据库中:Codeigniter

    我正在尝试将不同用户的图片路径上传到数据库中 我对 codeigniter 很陌生 并且阅读了很多教程 但我仍然在挣扎 这是我的控制器 但我什至不知道如何将图像与用户会话链接 这是我的代码 function do upload config
  • 将私有 GitLab 的依赖项与 NPM 结合使用

    我正在尝试从私有 GitLab 实例安装 NPM 依赖项 所以 我有带有基本文件的存储库 我在中添加了这个依赖项package json在我的项目上 node demo package https oauth2
  • 通过ajax请求提交html表单? [复制]

    这个问题在这里已经有答案了 可能的重复 jQuery AJAX 提交表单 https stackoverflow com questions 1960240 jquery ajax submit form 我在页面 A 上有一个表单 而不是
  • 在 Three.js 中渲染具有大量对象的多个场景的最佳方式

    想象一下 您想要绘制两个场景 每个场景都有数百个球体 并提供在这些场景之间切换的功能 做到这一点的最佳方法是什么 目前 一个开关大约需要 4 到 5 秒 因为我要删除 创建和绘制每个开关上的所有球体 下面是在场景切换上运行的代码示例 cle
  • 如何在react redux中实现一个自包含组件?

    我正在基于react redux构建一个文件管理器webui 我的目的是通过这个项目掌握react和redux 如您所知 文件管理器需要一个树浏览器 我想构建一个可以包含它自己并且每个都有自己状态的组件 像下面这样 TreeNode可以包含
  • Chrome 是否已停止支持 Intl 函数?

    我使用的是 Chrome 浏览器 版本 92 0 4515 131 我发现对 JavaScript Intl 的支持不能正常运行Chrome浏览器 const formattedDate new Intl DateTimeFormat nb
  • 如何借助 XSLT 取消转义转义 XML 内容?

    我的问题是如何取消转义已经转义的 xml 我尝试了 Tomalak 提供的代码来响应如何借助 XSLT 转义 XML 字符 https stackoverflow com questions 2463155 how to unescape
  • 让 Git 确认之前移动的文件

    我不假思索地手动移动了一堆文件 并且找不到一种方法让 git 识别这些文件只是被移动 而不是实际上不同的文件 除了删除旧的并添加新的 从而丢失历史记录 或使用 git mv 重做所有更改之外 还有其他方法可以做到这一点吗 要让 git 删除
  • OnPreferenceChange Listener 和 OnSharedPreferenceChangeListener 之间有什么不同

    我想获取复选框首选项的值 哪种方法适合聆听喜好 OnPreferenceChange Listener 和 OnSharedPreferenceChangeListener 之间的真正区别是什么 UPDATE为什么 onSharedPref
  • 即使收到 200,angularjs $http.jsonp 也会转到 .error 而不是 .success

    我正在构建一个 AngularJS 应用程序 它调用一个从数据库获取数据的 NodeJS 服务器 NodeJS 返回 JSON stringify someArrayWithData 这是 AngularJS 代码 scope getMai
  • 对 MasterController::StaticMetaObject 的未定义引用

    我刚刚开始学习 Qt 目前正在阅读这本书学习 Qt 5 作者 Nicolas Sheriff 在我所在的位置 在第 2 章中 我遵循所有说明 并且理解我在做什么 但我陷入了一件事 当我与其他程序一起编译以下程序时 我收到此错误列表 显示错误
  • 为什么这段 C# 代码不起作用?我正在尝试将 shell 的输出读取到 TortoiseHG (Mercurial)

    我正在尝试让 Mercurial 在我的 C wpf 应用程序的 shell 中运行 我的目的是将输出检索到字符串中 以便我可以解析它 对我来说不幸的是 hg exe 来自 tortoiseHg 似乎不会通过下面的代码返回任何内容 其他 e
  • 如何在 Mac 上安装支持 GPU 的 TensorFlow?

    我的 MacBook Pro 没有 NVIDIA GPU 所以不可能运行CUDA 我想知道哪些早期版本的 TensorFlow 支持 Mac OS 的 GPU 我如何在 Anaconda 上安装 如上所述official https www
  • 时区显示值与给定时区的 GMT 偏移量?

    我想构建一个时区列表以显示给用户选择 显示名称必须类似于 GMT 5 30 India Standard Time Asia Calcutta 我正在使用所有时区TimeZone getAvailableIDs 并构建列表 我写的代码是 S
  • 初始化 C++ 向量的大小

    初始化 C 向量以及其他容器的大小有哪些优点 如果有 有什么理由不只使用默认的无参数构造函数吗 基本上 两者之间是否存在显着的性能差异 vector