C++ 中的大括号语法和迭代器

Curly bracket syntax and iterator in c++

我对 C++11 有疑问。我知道下面的函数反转字符串,但我不知道 {} 语法是什么?那是什么类型的结构?我通常在 Java 中编码。我不知道这是什么?

string reverseString(string str){
    return{ str.rbegin(), str.rend() };
}

我还有一个问题,这种反转字符串的方法效率如何?因为我认为如果我们想要在内存中连续的字符串,我们应该改变字符的位置。

这段代码也可以写成:

string reverseString(string str){
    return string(str.rbegin(), str.rend());
}

它使用从两个迭代器(开始和结束)创建新字符串的范围构造函数。

感谢统一初始化,您可以将其写为:

string reverseString(string str){
    return string{str.rbegin(), str.rend()};
}

并且因为编译器已经知道 return 类型是 string,所以你不必明确指定它,这导致了这个 "weird" 语法:

string reverseString(string str){
    return {str.rbegin(), str.rend()};
}

正在使用的是Uniform Initialization

看起来有点奇怪,我承认。该函数知道它需要 return 一个 string,但是它被提供了一对迭代器。大括号允许编译器尝试根据大括号的内容构造 string,果然,constructor number six listed here 将尝试从开始和结束迭代器构造字符串。

所以

return {str.rbegin(), str.rend()};

语法更熟悉

return string(str.rbegin(), str.rend());

下一个魔法是 rbeginrend 提供反向迭代器,因此输入 string 将被反向读入输出 string

string个迭代器are Random Access Iterators,所以迭代器会在O(N)时间内遍历。构建新字符串、复制旧字符串以及调整缓冲区大小并没有那么神奇,新字符串将在 O(N) 时间加上任何需要调整支持新字符串的缓冲区大小的时间 string.

这会导致

  • O(N) 复杂度,因为在将 N 个元素从一个 string 复制到另一个或
  • 之前,缓冲区已预先调整大小
  • Amortized O(N) 复杂度,因为缓冲区会按需调整大小,导致一些额外的分配和将旧缓冲区复制到新缓冲区以及从一个 string 复制到另一个。

第二个选项是可能的,因为 string 构造函数不要求输入迭代器是随机访问的,这使得计算预调整所需缓冲区的大小可能比调整大小更昂贵。但它可能有一个针对随机访问和预调整的特殊情况测试。