为什么 std::stringstream 不能与 std::string_view 一起使用?

Dmi*_*nov 5 c++ istringstream string-view c++17

初始化std::stringstream 构造函数接受const string&以下参数:

explicit stringstream (const string& str,
                       ios_base::openmode which = ios_base::in | ios_base::out);
Run Code Online (Sandbox Code Playgroud)

这个接口在 C++98 中是合理的,但从 C++17 开始,我们有了std::string_view表示字符串的类的更便宜的替代方案。该类std::stringstream不会修改它接受的字符串,不拥有它,也不要求它以空终止。那么为什么不添加另一个接受 的构造函数重载呢std::string_view?是否存在任何障碍使该解决方案不可能(或不合理)屈服于Boost::Iostreams等替代方案?

Nic*_*las 9

在这一点上(即:当我们接近 C++23 时),它没有太多意义。

由于您使用的stringstream是而不是更特定于用途的版本之一,因此有两种可能性:您要么打算能够写入流,要么不想。

如果您不打算写入流,则不需要复制数据。所有形式都stringstream拥有其作用的角色,所以你应该尽量避免复制。您可以使用 C++23 类型ispanstream(旧类型的替代品strstream)。这需要 a span<const CharT>,但也string_view 应该与其中一个ispanstream构造函数兼容。

如果您确实打算写入流,那么您将需要将数据复制到stringstream. 但您无需执行两份副本。所以 C++20 给出了stringstream一个来自std::string. 请参阅此处的构造函数#6:

explicit basic_stringstream( std::basic_string<CharT,Traits,Allocator>&& str,
                             std::ios_base::openmode mode = 
                             std::ios_base::in | std::ios_base::out );
Run Code Online (Sandbox Code Playgroud)
  1. 使用 移动构造底层字符串设备的内容str。底层basic_stringbuf对象被构造为basic_stringbuf<Char,Traits,Allocator>(std::move(str), mode).

由于std::string可以从 a 构造string_view,因此将 a 传递std::string_view到std::stringstream构造函数将使用此移动构造函数重载,这应该最大限度地减少复制。

所以实际上不需要string_view特定的构造函数。