在实现 C++1zstd::basic_string_view
以在较旧的编译器上使用它时,我遇到了流输出运算符重载的问题。基本上,它必须输出由string_view
while 引用的内容,而不依赖于存在的任何空终止符(因为string_view
不保证为空终止)。
通常,编写重载 foroperator<<
非常容易,因为您可以依赖已经存在的重载,因此不需要使用SO 上这个问题中提到的哨兵对象。
但是在这种情况下,没有预定义的重载来operator<<
获取字符指针和长度(显然)。因此,我std::string
在当前的实现中创建了一个临时实例:
template< typename TChar, typename TTraits >
auto operator<<(::std::basic_ostream<TChar, TTraits>& p_os, basic_string_view<TChar, TTraits> p_v)
-> ::std::basic_ostream<TChar, TTraits>&
{
p_os << p_v.to_string(); // to_string() returns a ::std::string.
return p_os;
}
这行得通,但我真的不喜欢我必须创建一个临时实例的事实std::string
,因为这需要冗余复制数据和动态内存的潜在使用。至少在我看来,这违背了使用轻量级引用类型的目的。
所以我的问题是:
在没有开销的情况下为我的 string_view 实现正确格式化输出的最佳方法是什么?
在研究时,我发现 LLVM 是这样做的:(在此处找到)
// [string.view.io]
template<class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv)
{
return _VSTD::__put_character_sequence(__os, __sv.data(), __sv.size());
}
的实现__put_character_sequence
驻留在这个文件中,但它大量使用内部函数来进行格式化。我需要自己重新实现所有格式吗?