【问题标题】:Explicitly specify specify string to write to for std::ostringstream为 std::ostringstream 显式指定要写入的字符串
【发布时间】:2015-03-30 01:05:55
【问题描述】:

我有一个代码,它使用 std::ostringstream 向 std::string 写入一个数字:

        template<class T>
        class Converter
        {
        private:
            static std::string s_buffer;     
        public:
            static const char* Out(const T& val)
            {
                std::ostringstream os;
                os << val;
                s_buffer = os.str();
                return(s_buffer.data());
            }
        };

Converter::Out 被调用了很多。以至于它甚至出现在分析器中。基本上,这里发生的是:

  1. 创建了一个 ostringstream 的实例
  2. 它创建一个要写入和写入的缓冲区
  3. 我将该缓冲区复制到静态字符串并返回

我认为,如果我可以让流直接写入静态字符串,从而避免复制,我可能会获得一些性能提升。但是我该怎么做 - std::ostringstream 在构造函数中只能接受 const std::string,这将是一个初步填充,而不是要写入的缓冲区。 也许 Boost 有其他选择,虽然我没有找到... :(

【问题讨论】:

  • 可以通过调用streambuf::pubsetbuf然后从streambuf构造流来指定你自己的缓冲区,但不幸的是它给你一个不可调整大小的缓冲区。
  • @vsoftco 我认为这是完全符合标准的代码,我希望好的实现能够做到这一点。问题是实际上有多少实现...
  • @jrok,我认为你不能从 std::stringstream 移动...你绝对可以移动返回的字符串(我认为编译器应该自动执行此操作,因为 std::string 有一个移动构造函数/赋值运算符)
  • 您是否尝试过将std::ostringstream osalso 类设为静态?另外,考虑通过返回std::string来更改函数签名(并从RVO中受益),如有必要,调用者可以调用std::string::c_str()

标签: c++ stl stream


【解决方案1】:

您可以使用rdbuf() 方法访问ostringstream 的缓冲区;不幸的是,对底层字符缓冲区的访问受到保护。但是,您可以通过继承轻松解决这个问题:

template<class T>
class Converter
{
private:
    static struct Buf : public std::ostringstream, public std::basic_stringbuf<char>
    {
        Buf() { static_cast<std::basic_ios<char>&>(*this).rdbuf(this); }
        void clear() { setp(pbase(), pbase()); }
        char const* c_str() { *pptr() = '\0'; return pbase(); }
    } s_buf;
public:
    static const char* Out(const T& val)
    {
        s_buf.clear();
        s_buf << val;
        return s_buf.c_str();
    }
};

如果 Boost 是一个选项,您可以使用由 stringvector&lt;char&gt; 支持的 boost::iostreams::filtering_ostreamhttp://lists.boost.org/boost-users/2012/09/75887.php

【讨论】:

  • 这比原来的程序有什么好处?
  • @0x499602D2 它不涉及字符串复制。
  • 哇,你建议的代码真的飞了!将在 Converter::Out 中花费的总时间从整个执行时间的 3.5% 降低到 1.5%。另一方面,Boost 示例比我的原始代码差很多(13%)。
猜你喜欢
  • 2014-12-03
  • 2020-09-26
  • 1970-01-01
  • 2014-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-23
相关资源
最近更新 更多