rub*_*nvb 10 c++ initialization const c++11
也许已经有人问过类似的东西,当然,这是一个挑剔......
我有一堆常量std::map来在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"} };
Run Code Online (Sandbox Code Playgroud)
C++ 11 constexpr会对性能产生任何影响,还是假设运行时初始化惩罚错误?我认为编译器可以在可执行文件中嵌入一个常量STL容器作为纯数据,但显然这可能不像我说的那么简单?
Joh*_*itb 18
初始化的性能不是一个问题,而是初始化的顺序.如果某人在main开始之前使用了您的地图(例如在初始化命名空间范围变量时),那么您就是SOL,因为您不能保证在用户初始化之前已经初始化了地图.
但是你可以在编译时做这件事.字符串文字是常量表达式,枚举数也是如此.简单的线性时间复杂度结构
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);
}
Run Code Online (Sandbox Code Playgroud)
如果value(a, b)在常量表达式上下文中使用,并且指定的名称不存在,则会出现编译时错误,因为函数调用将变为非常量.
要value(a, b)在非常量表达式上下文中使用,最好添加安全功能,例如在数组中添加结束标记,value如果点击结束标记则抛出异常(只要你从不,函数调用仍然是一个常量表达式击中结束标记).