为什么emplace_back(“ Hello”)调用strlen?

时间:2018-07-07 03:53:50

标签: c++ stdvector stdstring

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&& parametermy tests show that the string literal shouldn't be decaying to a pointer here。显然我正在忽略某些东西。

1 个答案:

答案 0 :(得分:8)

strlen调用位于慢速路径的离线函数体中;该函数体必须对所有类型为const char (&)[42]的参数(在您的戈德螺栓示例中)均有效,包括不是源自41个字符且没有嵌入null的字符串文字的参数。

快速路径内联到foo中,并且确实在编译时计算长度。