我应该将 std::string 与 "string" 或 "string" s 进行比较吗?

Should I compare a std::string to "string" or "string"s?

本文关键字:string 比较 std 我应该      更新时间:2023-10-16

考虑以下代码片段:

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
}

乍一看,似乎与const char*进行比较需要较少的汇编指令1,因为使用字符串文字将导致std::string的就地构造。

(编辑:正如答案中指出的那样,我忘记了这样一个事实,即有效的s.compare(const char*)将在foo()中调用,因此在这种情况下当然不会进行就地施工。因此在下面划掉几行。

但是,查看operator==(const char*, const std::string&)参考:

所有比较都是通过compare()成员函数完成的。

根据我的理解,这意味着无论如何我们都需要构造一个std::string才能进行比较,所以我怀疑开销最终会是一样的(尽管被调用operator==隐藏了)。

  • 我应该更喜欢哪种比较?
  • 一个版本是否比另一个版本有优势(可能在特定情况下)?

1我知道更少的汇编指令并不一定意味着更快的代码,但我不想在这里讨论微观基准测试。

两者都不是。

如果你想聪明,与"string"sv进行比较,它会返回一个std::string_view


虽然与文本(如"string")进行比较不会导致任何分配开销,但它被视为以 null 结尾的字符串,具有所有伴随的缺点:对嵌入的 null 不容忍,用户必须注意 null 终止符。

"string"s执行分配,除非小字符串优化或分配省略。此外,运算符将传递文本的长度,无需计数,并且允许嵌入 null。

最后,使用"string"sv结合了其他两种方法的优点,避免了它们各自的缺点。此外,std::string_view是比std::string简单得多的野兽,特别是如果后者像所有现代人一样使用SSO。


至少从 C++14 开始(通常允许省略分配),编译器理论上可以优化最后一个选项的所有选项,前提是有足够的信息(通常可用于示例)和工作量,根据 as-if 规则。不过,我们还没有到达那里。

不,compare()不需要为const char*操作数构造std::string

您在此处使用重载 #4。

与字符串文字的比较是您正在寻找的"免费"版本。在此处实例化std::string是完全没有必要的。

根据我的理解,这意味着无论如何我们都需要构造一个std::string才能进行比较,所以我怀疑开销最终会是一样的(尽管被调用operator==隐藏了)。

这就是推理出错的地方。std::compare不需要将其操作数分配为 C 样式的以 null 结尾的字符串即可运行。根据其中一个重载:

int compare( const CharT* s ) const; // (4)

4) 将此字符串与以 null 结尾的字符序列进行比较,该字符序列从长度为Traits::length(s)的字符s开始。

尽管是否分配是一个实现细节,但序列比较这样做似乎并不合理。