c++ - constexpr 和初始化

标签 c++ initialization constants c++11

也许已经有人问过类似的问题,当然,这是一个吹毛求疵...

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

作为说明性示例,这里是其中一张 map 的示例:

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 开始之前使用你的 map (例如在命名空间范围变量的初始化时),那么你就是 SOL,因为你不能保证你的 map 在用户初始化使用它之前已经初始化.

但是您可以在编译时做这件事。字符串文字是常量表达式,枚举数也是如此。一个简单的线性时间复杂度结构

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),并且您指定的名称不存在,您将收到编译时错误,因为函数调用将变成非持续的。

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

关于c++ - constexpr 和初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8026906/

相关文章:

c - K&R C 中的数组是如何初始化的?

c - 字符数组和整型数组的区别

ruby-on-rails - 在 Rails 中实例化对象时如何初始化属性?

php - PHP 中的路径常量

c++ - 我应该声明方法 "const"如果它只是 "shallow const"而不是 "deep const"吗?

c++ - 如何应对高频数据?

c++ - OpenMAX 和 NDK : Where I can get the surface?

C++将整数映射到 bool 数组

c++ - 检查参数时首选哪一个?

c++ - 堆分配的 const 对象与非 const 对象有何不同?