std::string s1 {"现代 C++", 3} 与 std::string s1 {str, 3}

dbe*_*rfa 69 c++ string c++17

以下代码的输出让我感到困惑:

const std::string str = "Modern C++";

std::string s1 {"Modern C++", 3};
std::string s2 {str, 3};

std::cout << "S1: " << s1 << "\n";
std::cout << "S2: " << s2 << "\n";
Run Code Online (Sandbox Code Playgroud)

输出:

> S1: Mod
> S2: ern C++
Run Code Online (Sandbox Code Playgroud)

谁能解释这个结果?

0RR*_*0RR 66

从:

https://en.cppreference.com/w/cpp/string/basic_string/basic_string

std::string s1 {"Modern C++", 3};
Run Code Online (Sandbox Code Playgroud)

使用以下构造函数:

basic_string( const CharT* s,
          size_type count,
          const Allocator& alloc = Allocator() );
Run Code Online (Sandbox Code Playgroud)

所以需要 3 个字符才能得到Mod.

std::string s2 {str, 3};
Run Code Online (Sandbox Code Playgroud)

将使用以下构造函数:

basic_string( const basic_string& other,
          size_type pos,
          const Allocator& alloc = Allocator() );
Run Code Online (Sandbox Code Playgroud)

所以从位置 3 开始取字符串给 : ern C++

  • 人们不得不问他们为什么要添加两个行为如此不同的构造函数。就好像完全没有经过思考就拼凑起来的一样。 (28认同)
  • @Polygnome:“完全没有想到就拼凑在一起”基本上描述了整个`std::string`。它还考虑了基于索引和基于迭代器的方法的混合——字符串是独立于 STL 开发的,然后追溯增强以匹配——并且通常有太多的“便捷方法。我总是喜欢 [GOTW #84: Monoliths Unstrung](http://www.gotw.ca/gotw/084.htm),它深入研究了一个最小的字符串 API,并辅以自由函数。 (4认同)
  • 谢谢。第一个是“size_type count”,第二个是“size_type pos”。 (3认同)
  • 这个子字符串构造函数是否有一个用例不能由“substr”方法提供? (2认同)

Yak*_*ont 35

一个是打电话string(char const*, count),另一个string(string const&, pos)

一个从缓冲区中获取前 3 个字符,另一个获取第 3 个字符之后的所有字符。

这是因为 C++ 具有原始字符缓冲区和标准字符串。 "this is not a std::string". "this is a std string"s, std::string so_is="this";.

std::string 已有30多年的历史,并且在没有足够小心的情况下被添加到C++语言中(与STL不同,它在添加之前经历了更多的迭代)。

老实说,它的界面太丰富了,你可能会遇到这样的东西;导致混乱结果的多个重载。


ein*_*ica 7

谁能向我解释这是为什么?

那是因为std::string有它不应该的构造函数(@ORR解释了细节)。它不应该有这些构造函数,因为:

  1. 使用命名构造函数习语/ std::string方法和现有构造函数可以轻松实现它们的效果- 无需额外成本(至少在 C++11 中),并且
  2. 仅通过查看构造函数调用来理解构造函数参数的使用方式并不明显和微不足道。

这不是标准库中具有这种不良(恕我直言)构造函数的唯一情况;std::vector构造函数种类繁多和令人困惑/误导性的构造函数语义而(臭名昭著)。

人生课程:

  • 省略构造函数;并非所有用于构造类对象的常用值都应该有自己的构造函数;
  • 相反,使用命名构造函数惯用语
  • 让你的代码审查者或其他一些不那么偏见的人阅读你的构造函数的调用,以判断每个构造函数的含义是否足够明显。