constexpr和初始化 [英] constexpr and initialization

查看:116
本文介绍了constexpr和初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许已经有人问过类似的问题,而且肯定是个问题……

Perhaps something similar has already been asked, and sure, it's a nitpick...

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

I have a bunch of constant std::maps to switch between enum (class) values and their std::string representations (both ways). Someone here pointed out to me that these maps will be initialized at runtime, when other initialization code is run, before my program executes all the good stuff. This would mean constant expressions would impact runtime performance, as the maps are built up from their enum-string pairs.

作为说明性示例,以下是其中一个示例这些地图:

As an illustrative example, here is an example of one of these maps:

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容器作为纯数据嵌入可执行文件中,但是显然这可能不像我说的那么容易?

Would the C++11 constexpr have any influence on performance, or is my assumption of a runtime initialization penalty false? I would think a compiler can embed a constant STL container as pure data in the executable, but apparently that may not be as easy as I make it sound?

推荐答案

不是很多问题,而是初始化的顺序。如果有人在 main 启动之前使用了您的地图(例如,在初始化命名空间范围变量时),那么您就是SOL,因为您不能保证地图已经初始化在用户初始化使用它之前。

It's not so much the performance of initialization that is a problem, but the order of initialization. If someone uses your map before main has started (for example at initialization for a namespace scope variable), then you are SOL, because you are not guaranteed that your map has been initialized before the user's initialization uses it.

但是您可以在编译时执行此操作。字符串文字和枚举数都是常量表达式。一个简单的线性时间复杂度结构

However you can do this thing at compile time. String literals are constant expressions, as are enumerators. A simple linear-time complexity structure

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)在常量表达式上下文中,并且您指定的名称不存在,您会收到编译时错误,因为函数调用将变为非常量。

If you use value(a, b) in a constant expression context, and the name you specify doesn't exist, you will get a compile time error because the function call would become non-constant.

要在非恒定表达式上下文中使用 value(a,b),最好添加安全功能,就像在数组中添加结束标记并在 value 中抛出异常(如果您按下了结束标记(只要您从未点击过,函数调用仍将是一个常量表达式)结束标记)。

To use value(a, b) in a non-constant expression context, you better add safety features, like adding an end marker to your array and throwing an exception in value if you hit the end marker (the function call will still be a constant expression as long as you never hit the end marker).

这篇关于constexpr和初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆