我正在开发具有大量静态字符串的库。为了稍微优化运行时,这些字符串应该从以空字符结尾的字符串(经典的C风格char数组)更改为预先知道长度的结构,如std::string
或std::string_view
或自定义指针+长度对。 std::string
是众所周知且多功能的,但缺点是占用空间较大(至少在x64上为32位),并且如果不适用于小字符串优化,则会产生VM开销和运行时成本,而这种情况适用于我的大多数数据。 string_view
听起来是最合适的候选项,只要我能确保数据以空字符结尾(虽然string_view
本身没有此类保证,但可以通过惯例来减轻风险)。
仍然很重要的问题:现代编译器是否使用内部的strlen
而不使用O^(n)的常量复杂度进行预初始化string_view
? 如果是,则保留空字符终止符吗?
当然,我可以添加一些宏来初始化string_views
,但那样会很麻烦。 类似于:
#define foo(buf) foo, (sizeof(foo)-1)
const string_view svMyVar(foo("original C-string value"));
我希望编译器能为我简化这个过程。
#define foo(buf) buf, (sizeof(buf)-1)
吗? - 463035818_is_not_a_numberchar const str[] = "foobar";
,这样编译器就可以确定数组的大小,并且您可以通过类型系统查询它。理论上,这允许一个构造函数string_view(char(&)[N])
,它保证在编译时计算字符串的“长度”,但是标准库中没有这样的构造函数。 - dyp"foobar"sv
,在这种情况下,编译器同样知道字符串长度,并将其传递给函数operator""(char const*, size_t)
。除此之外,您还可以拥有constexpr string_view x = ...;
,合理优化的编译器应该在编译时初始化它。 - dyp-O1
时就已经将其字符串长度计算解析为编译时。使用sv
用户定义字面量也可以在没有优化的情况下在编译时解析出长度。 - dyp