我应该将 std::string 与 "string" 还是 "string" 进行比较?

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

考虑这个代码片段:

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
}

first sight,看起来与 const char* 相比需要更少的汇编指令1,因为使用字符串文字会导致 in- std::string.

的位置构造

(编辑:正如答案中所指出的,我忘记了实际上 s.compare(const char*) 将在 foo() 中被调用的事实,所以当然在这种情况下没有就地施工。因此删除下面的一些行。)

但是,看着 operator==(const char*, const std::string&) reference:

All comparisons are done via the compare() member function.

根据我的理解,这意味着我们无论如何都需要构造一个 std::string 来执行比较,所以我怀疑最终开销会相同(尽管隐藏在对operator==).

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

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

您正在使用 overload #4 here

与字符串文字的比较是您要查找的 "free" 版本。在这里实例化一个 std::string 是完全没有必要的。

From my understanding, this means that we will need to construct a std::string anyway in order to perform the comparison, so I suspect the overhead will be the same in the end (although hidden by the call to operator==).

这就是推理错误的地方。 std::compare 不需要将其操作数分配为 C-style null-terminated 字符串来运行。根据其中一个重载:

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

4) Compares this string to the null-terminated character sequence beginning at the character pointed to by s with length Traits::length(s).

虽然是否分配是一个实现细节,但顺序比较似乎并不合理。

都没有。

要聪明就比较"string"sv, which returns a std::string_view.


虽然与 "string" 这样的文字进行比较不会产生任何 allocation-overhead,但它被视为以空字符结尾的字符串,并具有所有伴随的缺点:不能容忍嵌入的空值,用户必须注意空终止符。

"string"s 进行分配, or 除外。此外,运算符会传递文字的长度,无需计数,并且它允许嵌入空值。

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


至少从 C++14(通常允许省略分配)开始,编译器在理论上可以将所有选项优化到最后一个,只要有足够的信息(通常可用于该示例)和努力,在 as-if rule.不过我们还没有。