【问题标题】:std::string::assign vs std::string::operator=std::string::assign 与 std::string::operator=
【发布时间】:2016-03-15 17:51:18
【问题描述】:

我很久以前在 Borland C++ 中编码,现在我试图理解“新”(对我而言)C+11(我知道,我们在 2015 年,有一个 c+14 ......但我正在开发一个 C++11 项目)

现在我有几种方法可以为字符串赋值。

#include <iostream>
#include <string>
int main ()
{
  std::string test1;
  std::string test2;
  test1 = "Hello World";
  test2.assign("Hello again");

  std::cout << test1 << std::endl << test2;
  return 0;
}

它们都有效。我从http://www.cplusplus.com/reference/string/string/assign/ 了解到,还有另一种使用assign 的方法。但是对于简单的字符串赋值,哪一个更好呢?我必须用 8 个 std:string 填充 100 多个结构,并且我正在寻找最快的机制(我不关心内存,除非有很大的不同)

【问题讨论】:

    标签: c++11 stdstring


    【解决方案1】:

    两者都同样快,但= "..." 更清晰。

    如果你真的想要快速,请使用assign 并指定大小:

    test2.assign("Hello again", sizeof("Hello again") - 1); // don't copy the null terminator!
    // or
    test2.assign("Hello again", 11);
    

    这样,只需要一次分配。 (您也可以事先.reserve() 足够的内存来获得相同的效果。)

    【讨论】:

    • 注意不要在 std::string 中包含来自 C 字符串的尾随 \0,如果您稍后尝试追加它,这会咬你。在上面的示例中,使用 11 的长度,而不是 12。
    • @KilianRosbach 哎呀,你当然是对的。现已修复。
    【解决方案2】:

    我尝试了两种方式的基准测试。

    static void string_assign_method(benchmark::State& state) {
      std::string str;
      std::string base="123456789";  
      // Code inside this loop is measured repeatedly
      for (auto _ : state) {
        str.assign(base, 9);
      }
    }
    // Register the function as a benchmark
    BENCHMARK(string_assign_method);
    
    static void string_assign_operator(benchmark::State& state) {
      std::string str;
      std::string base="123456789";   
      // Code before the loop is not measured
      for (auto _ : state) {
        str = base;
      }
    }
    BENCHMARK(string_assign_operator);
    

    Here 是图形比较解决方案。似乎这两种方法都同样快。赋值运算符有更好的结果。

    仅当必须分配基本字符串中的特定位置时才使用 string::assign。

    【讨论】:

    • 谢谢。我不知道 quick-bench,它看起来是个很棒的工具。对于 c++ 11,很奇怪地看到取决于编译器(clang、gcc),其中一个或另一个更快。
    • 是的!它使人们能够快速决定使用哪种方法。您还可以同时对 2 段以上的代码进行基准测试。
    • string_assign_method 有一点问题。它调用了 std::string::assign 的错误重载。您本质上是在复制一个空字符串。您应该改为:str.assign(base, 0, 9);。基准测试结果不受影响