and*_*eee 44 c++ string-comparison string-literals c++14 c++17
考虑以下代码片段:
bool foo(const std::string& s) {
return s == "hello"; // comparing against a const char* literal
}
bool bar(const std::string& s) {
return s == "hello"s; // comparing against a std::string literal
}
Run Code Online (Sandbox Code Playgroud)
在乍一看,它看起来像比对并const char*需要更少的组装说明1,作为使用字符串字面量会导致就地建设std::string。
(编辑:正如答案中指出的那样,我忘记了有效地s.compare(const char*)将被调用的事实foo(),因此在这种情况下当然不会进行就地构建。因此,请在下面删除一些行。)
但是,请operator==(const char*, const std::string&)参阅参考资料:
所有比较都是通过
compare()成员函数完成的。
根据我的理解,这意味着我们将需要构造一个结构 std::string来执行比较,因此我怀疑最终的开销将是相同的(尽管对的调用已将其隐藏了operator==)。
1我知道更少的汇编指令并不一定意味着更快的代码,但是我不想在这里进行微基准测试。
Ded*_*tor 66
如果您想变得聪明一点,请与进行比较"string"sv,以返回std::string_view。
虽然与类似的文字进行比较"string"不会导致任何分配开销,但会将其视为以null结尾的字符串,同时具有所有伴随的缺点:不能容忍嵌入的null,用户必须注意null终止符。
"string"s进行分配,除非进行小字符串优化或分配省略。而且,运算符可以传递文字的长度,无需计数,并且允许嵌入空值。
最后使用"string"sv结合了其他两种方法的优点,避免了它们各自的缺点。而且,a std::string_view比a兽简单得多std::string,尤其是当a 像所有现代动物一样使用SSO时。
在因为C语言至少++ 14(一般允许eliding分配),编译器在理论上可以优化给予足够的信息,所有的选择到最后一个,(一般适用于例如)和努力,在AS-如果规则。我们还没到那儿。
根据我的理解,这意味着我们将需要构造一个结构
std::string来执行比较,因此我怀疑最终的开销将是相同的(尽管对的调用已将其隐藏了operator==)。
这就是推理出错的地方。std::compare不需要将其操作数分配为C样式的以null终止的字符串即可起作用。根据重载之一:
int compare( const CharT* s ) const; // (4)
Run Code Online (Sandbox Code Playgroud)
4)在由指向的字符比较此字符串的空终止字符序列开始
s与长度Traits::length(s)。
尽管是否分配是实现细节,但是序列比较这样做似乎并不合理。