我应该将std :: string与“ string”或“ string” s比较吗?

时间:2019-06-03 12:42:30

标签: c++ c++14 c++17 string-comparison string-literals

请考虑以下代码段:

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 ,因为使用字符串文字将导致{的就地构造{1}}。

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

  

所有比较都是通过std::string成员函数完成的。

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

编辑:如答案中所指出,我忘记了实际上将在operator==中调用s.compare(const char*)的事实,因此当然就地构建不需要在这种情况下放置

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

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

3 个答案:

答案 0 :(得分:65)

都不是。

如果您想变得聪明一点,可以将其与"string"sv进行比较,后者将返回std::string_view


"string"之类的文字进行比较时,不会导致任何分配开销,但会将其视为以null结尾的字符串,同时具有所有伴随的缺点:不能接受嵌入的null,用户必须注意null终止符

"string"s进行分配,但禁止small-string-optimisationallocation elision。另外,运算符可以传递文字的长度,而无需计数,并且允许嵌入空值。

最后使用"string"sv结合了其他两种方法的优点,避免了它们各自的缺点。另外,std::string_viewstd::string更简单,尤其是当后者像所有现代人一样使用SSO时。


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

答案 1 :(得分:13)

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

您正在使用overload #4 here

与字符串文字的比较是您要查找的“免费”版本。完全不需要在此处实例化std::string

答案 2 :(得分:9)

  

据我了解,这意味着无论如何我们都需要构造一个std::string才能进行比较,因此我怀疑最终的开销是一样的(尽管对{{ 1}})。

这就是推理出错的地方。 std::compare不需要将其操作数分配为C样式的以null终止的字符串即可起作用。根据重载之一:

operator==
  

4)将此字符串与以int compare( const CharT* s ) const; // (4) 指向的字符(长度为s所指向的字符开始的以空终止的字符序列进行比较。

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