constexpr 和初始化

2024-03-22

也许已经有人问过类似的问题了,当然,这是一个挑剔的问题......

我有一堆常数std::maps 之间切换enum (class)价值观及其std::string表示(双向)。这里有人向我指出,这些映射将在运行时初始化,当其他初始化代码运行时,在我的程序执行所有好东西之前。这意味着常量表达式会影响运行时性能,因为映射是根据枚举字符串对构建的。

作为说明性示例,以下是其中一张地图的示例:

enum class os
{
    Windows,
    Linux,
    MacOSX
};
const map<string, os> os_map =
     { {"windows", os::Windows},
       {"linux",   os::Linux},
       {"mac",     os::MacOSX} };
const map<os, string> os_map_inverse =
     { {os::Windows, "windows"},
       {os::Linux,   "linux"},
       {os::MacOSX,  "mac"} };

C++11会吗constexpr对性能有任何影响,还是我对运行时初始化惩罚的假设是错误的?我认为编译器可以将常量 STL 容器作为纯数据嵌入到可执行文件中,但显然这可能不像我说的那么容易?


问题不在于初始化的性能,而在于初始化的顺序。如果有人之前使用过您的地图main已经开始(例如在命名空间作用域变量的初始化时),那么您就是 SOL,因为您无法保证您的映射在用户初始化使用它之前已被初始化。

然而你can在编译时做这件事。字符串文字是常量表达式,枚举器也是如此。简单的线性时间复杂度结构

struct entry {
  char const *name;
  os value;
};

constexpr entry map[] = {
  { "windows", os::Windows },
  { "linux", os::Linux },
  { "mac", os::Mac }
};

constexpr bool same(char const *x, char const *y) {
  return !*x && !*y ? true : (*x == *y && same(x+1, y+1));
}

constexpr os value(char const *name, entry const *entries) {
  return same(entries->name, name) ? entries->value : value(name, entries+1);
}

如果你使用value(a, b)在常量表达式上下文中,并且您指定的名称不存在,您将收到编译时错误,因为函数调用将变得非常量。

To use value(a, b)在非常量表达式上下文中,您最好添加安全功能,例如向数组添加结束标记并在value如果您击中结束标记(只要您从未击中结束标记,函数调用仍将是常量表达式)。

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

constexpr 和初始化 的相关文章

  • 从 Dropbox C# 下载文件[重复]

    这个问题在这里已经有答案了 我正在尝试下载 Dropbox 中的 pdf 文件 我需要将其保存到本地计算机中 可以是任何文件夹C Users User Desktop例如 这是我一直在使用的代码 public void DownloadPd
  • 数据结构的优化存储以实现快速查找和持久化

    Scenario 我有以下方法 public void AddItemSecurity int itemId int userIds public int GetValidItemIds int userId 最初我正在考虑表单上的存储 i
  • 在列表中查找匹配项的最简洁方法

    在列表中查找内容的最佳方式是什么 我知道 LINQ 有一些不错的技巧 但我们也可以获取有关 C 2 0 的建议 让我们对这个常见的代码模式进行最佳重构 目前我使用这样的代码 mObjList is a List
  • Windows 10 UWP 中的视觉状态管理器未在页面加载时应用初始状态

    我有一个带有相关面板的页面 可以根据宽度重新组织 但是 除非宽度 gt 720px 否则它似乎不会在加载时应用任何状态 如果我在加载页面后调整页面大小 则两种状态都有效 解决方法是检查加载页面上的窗口大小并手动选择状态 但我相信这应该自动处
  • 为什么不能使用initializer_list来初始化unique_ptr的向量? [复制]

    这个问题在这里已经有答案了 我想知道为什么initializer list 不能与unique ptr 一起使用 std vector
  • 如何自定义 ASP.Net Core 模型绑定错误?

    我只想从我的 Web API Asp net Core 2 1 返回标准化的错误响应 但我似乎不知道如何处理模型绑定错误 该项目刚刚从 ASP NET Core Web 应用程序 gt API 模板创建 我有一个简单的操作定义为 Route
  • ASP.NET Core 中 AsNoTracking 的模拟或更好的解决方法

    您如何模拟 AsNoTracking 或者是否有更好的解决方法来解决此问题 Example public class MyContext MyContextBase Constructor public MyContext DbContex
  • 使用 pthread_cond_signal 优雅地终止线程被证明是有问题的

    我需要发射一堆线程 并希望优雅地将它们拉下来 我正在尝试使用pthread cond signal pthread cond wait实现这一目标 但遇到了问题 这是我的代码 首先是thread main static void thrma
  • 通过 EUSART PIC18F45K80 打印消息

    我正在尝试向 Docklight 发送串行消息 但始终收到空值 我正在使用带有 XC8 MPLAB X 的 PIC18F45K80 我的代码中的所有内容似乎都是正确的 但我想我错了 我该如何修复它 include
  • memccpy 返回比 src 起始地址更低的内存地址

    我有一个学校项目 我必须重新编码memccpy 功能 我使用 2 个程序来检查我的代码是否正常工作 第一个是只有一个主程序的小程序 第二个程序是另一个学生开发的 可以找到here https github com yyang42 mouli
  • 如何实现可变虚拟成员函数

    所以我有这个功能 virtual void CallRemoteFunction const char pServerGameObjectId const char pFunctionName OVariant arg1 OVariant
  • 在 C++ 中初始化指针

    可以在声明时将指针分配给值吗 像这样的东西 int p 1000 是的 您可以在声明时初始化指向值的指针 但是您不能这样做 int p 1000 是个地址运算符 并且您不能将其应用于常量 尽管如果可以 那会很有趣 尝试使用另一个变量 int
  • C++ 虚拟关键字与重写函数

    我正在学习c 并且正在学习virtual关键字 我在互联网上搜索试图理解它但无济于事 我进入编辑器并做了以下实验 期望它打印两次基本消息 因为我的印象是需要 virtual 关键字来覆盖函数 然而 它打印出了两条不同的消息 有人可以向我解释
  • 函数中的重复参数检查

    我经常有调用层次结构 因为所有方法都需要相同的参数 如果我不想将它们放在实例级别 类的成员 那么我总是问我在每个方法中检查它们的有效性是否有意义 例如 public void MethodA object o if null o throw
  • Xamarin.Android JmDNS 绑定问题

    我开始研究 Xamarin Android 的 JmDNS 绑定 我设法构建了绑定 但无法从代码中引用它 https github com ytn3rd monodroid bindings tree master JmDNS https
  • PARITY_NONE 是 C++ Windows 中的关键字吗?

    我正在使用 boost 编写一个串行库 并且我有一个枚举 enum parity t PARITY NONE PARITY ODD PARITY EVEN 我收到如下错误 错误 1 错误 C2059 语法错误 我无法弄清楚问题是什么 然后我
  • 来自资源中 ImageSource 的 System.Drawing.Image

    我的问题与这个非常相似 wpf图像资源以及运行时在wpf控件中更改图像 https stackoverflow com questions 940592 wpf image resources and changing image in w
  • 不兼容的指针到字符转换

    我正在编写一个程序 将卡片值写入 52 个点字符的多维数组中 该程序是一个测试数组 稍后我将其作为函数写入主程序中 在程序中 我通过以下方式初始化 for 循环计数0通过51 我用一个switch语句调制13将卡牌值分配给数组点 但是 我收
  • 使用 Crypto++ 和 .NET 的 CFB 模式下的 TripleDES

    我正在尝试使用 TripleDES 使用 C 应用程序获得相同的结果 该应用程序具有Crypto https www cryptopp com 和 NET应用程序使用三重DESCryptoServiceProvider https msdn
  • 频繁插入已排序的集合

    我已经对集合 列表 进行了排序 并且我需要始终保持其排序 我目前在我的集合上使用 List BinarySearch 然后在正确的位置插入元素 我也尝试过在每次插入后对列表进行排序 但性能不可接受 有没有一种解决方案可以提供更好的性能 也许

随机推荐

  • MySql:插入一行并获取内容

    是否可以插入一行并获取在同一查询中插入的值 就像是 INSERT INTO items item number state SELECT 3 number state FROM item bug WHERE id 3 然后 获取ID并执行
  • return 语句中两种不同的括号语法

    我正在关注 ReactJS 入门教程 https scotch io tutorials learning react getting started and concepts https scotch io tutorials learn
  • 如何让 Google 字体在 IE 中工作?

    我一直在开发一个使用谷歌字体 API https code google com apis webfonts 它很棒 据说已经在 IE 中进行了测试 但是在 IE 8 中测试时 字体根本没有样式化 我包括了谷歌的字体指示 http code
  • Cuda和pytorch内存使用情况

    我在用Cuda and Pytorch 1 4 0 当我尝试增加batch size 我遇到以下错误 CUDA out of memory Tried to allocate 20 00 MiB GPU 0 4 00 GiB total c
  • TfidfVectorizer.fit_transfrom 和 tfidf.transform 之间有什么区别?

    在 Tfidf fit transform 中 我们仅使用参数 X 而没有使用 y 来拟合数据集 这是正确的吗 我们仅为训练集的参数生成 tfidf 矩阵 我们没有使用 ytrain 来拟合模型 那我们如何对测试数据集进行预测呢 https
  • 如何以编程方式禁用 TextView maxLines?

    我很难重置maxLines的属性TextView以编程方式 刚刚尝试设置为0但它不起作用 1使应用程序崩溃 我可以使用更简单的解决方法并设置maxLines to 5000但我不想那样做 有什么想法如何做到这一点吗 UPDATED 好吧 我
  • Android 首选项屏幕布局

    我的应用程序中有以下首选项屏幕
  • Android P 中调用服务的 AlarmManager:startForegroundService

    我正在使用 AlarmManager 如下所示 它在 Android O 及以下版本中运行良好 AlarmManager mgr AlarmManager context getSystemService Context ALARM SER
  • NumPy ndarray 的三元运算符?

    NumPy 有三元运算符吗 例如 在 R 中 有一个向量化的if else功能 gt ifelse 1 10 lt 3 a b 1 a a b b b b b b b b NumPy 中有类似的东西吗 您正在寻找numpy where ht
  • File.renameTo() 没有任何效果

    我希望能够重命名文件夹列表 以便删除不需要的字符 例如 点和双空格必须变成单个空格 单击 GUI 中的按钮后 您将看到一个带有正确格式名称的消息框 这表明格式正确并且函数被调用 当我查看我创建的测试文件夹时 名称没有更改 即使刷新后也没有更
  • 在 haskell 中将整数列表转换为一个 Int (如 concat)

    和标题说的差不多 我有一个整数列表 如下所示 1 2 3 我想将其更改为整数 123 我的第一个想法是 concat 但这不起作用 因为它的类型错误 我尝试了各种方法 但通常最终只是返回相同的列表 非常感谢任何帮助 另外 我已经找到了一种打
  • Java:如何在枚举中使用构造函数重载?

    我正在使用 Java 中的枚举 正如我所看到的 可以重载枚举构造函数 我的问题是 在这种情况下 是否有可能从构造函数重载中受益 因为据我所知 既不可能自己调用 它 也不可能强制编译器调用您想要调用的特定构造函数 感谢您花时间向我澄清这些内容
  • 在C++中,1和1i64有什么区别?

    我正在将一些 32 位兼容代码转换为 64 位 但我遇到了障碍 我正在编译 VS2008 x64 项目 并且收到以下警告 warning C4334 lt lt result of 32 bit shift implicitly conve
  • CodeIgniter 图像上传 - 无法显示错误消息

    这是我的上传模型 function upload avatar id this gt tank auth gt get user id config upload parameters and upload image config arr
  • PHP4 HTTP Post 不带 cURL

    我有以下代码 可在 PHP5 上运行 无需使用 cURL 即可发送 HTTP POST 我希望它可以在 PHP 4 3 0 及更高版本上运行 opts array http gt array method gt POST header gt
  • (Play 2.0) 设置 AnyContent 的最大 POST 大小

    我在 Play 2 0 中使用 Scala 每当将大数据 超过 100KB 发布到特定端点时 我都会收到 413 错误 它使用 anyContent 解析器 对于这个特定的 API 使用任何其他解析器是不合理的 Stack Overflow
  • Jenkins CLI 列表-带有文件夹的作业

    使用 Jenkins 文件夹插件时 有没有一种方法可以获取所有作业的列表 包括文件夹中的作业以及可能的文件夹路径 类似于默认 CLI 中的列表作业的工作方式 我制作了一个小型 PowerShell 脚本来获取默认仪表板中每个作业的最后一次构
  • Maven Shade 插件:如何解决警告消息“定义 1 重叠资源:[警告] - META-INF/MANIFEST.MF”

    For
  • 从文本文件读取到数组

    我正在尝试逐行读取文本文件并将其添加到数组中 当前代码和输出如下 我如何正确读取它 即将实际文本读入数组 而不是当前输出 VB NET 的控制台应用程序版本 Code Sub Main Dim file As String C path t
  • constexpr 和初始化

    也许已经有人问过类似的问题了 当然 这是一个挑剔的问题 我有一堆常数std maps 之间切换enum class 价值观及其std string表示 双向 这里有人向我指出 这些映射将在运行时初始化 当其他初始化代码运行时 在我的程序执行