Justin's answer在另一个问题上提出了一个观察,我发现这很有趣,但不能完全解释。考虑以下代码:
std::vector<std::string> v;
v.push_back("Hello, world!"); // Doesn't call strlen.
v.emplace_back("Hello, world!"); // Calls strlen.
如果您查看程序集,则emplace_back
generates a call to strlen
,而push_back
does not(已使用-Ofast
在gcc 8.1和clang 6.0中进行了测试)。
为什么会这样?为什么emplace_back
无法在此处优化strlen
的调用?我最初的想法是push_back
是在函数调用之前隐式创建std::string
(因此std::string
构造函数直接传递了字符串文字,可以对其进行最佳处理),而emplace_back
在函数调用之后的{em>之后中创建std::string
(因此std::string
构造函数是字符串文本的 forwarded ,假定已从const char [N]
衰减到const char *
,因此需要进行strlen
调用。
但是emplace_back
takes a T&&
parameter和my tests show that the string literal shouldn't be decaying to a pointer here。显然我正在忽略某些东西。
答案 0 :(得分:8)
strlen
调用位于慢速路径的离线函数体中;该函数体必须对所有类型为const char (&)[42]
的参数(在您的戈德螺栓示例中)均有效,包括不是源自41个字符且没有嵌入null的字符串文字的参数。
快速路径内联到foo
中,并且确实在编译时计算长度。