c++ - 将字符串移出 std::ostringstream

标签 c++ c++11 move-semantics ostringstream

如果我使用 std::ostringstream:

构造一个由空格分隔的浮点值列表组成的字符串
std::ostringstream ss;
unsigned int s = floatData.size();
for(unsigned int i=0;i<s;i++)
{
    ss << floatData[i] << " ";
}

然后我在 std::string:

中得到结果
std::string textValues(ss.str());

但是,这将导致不必要的字符串内容的深层复制,因为 ss 将不再使用。

有什么方法可以在不复制整个内容的情况下构造字符串?

最佳答案

std::ostringstream 不提供访问其内存缓冲区的公共(public)接口(interface),除非它不可移植地支持 pubsetbuf (但即便如此,您的缓冲区也是固定大小的,见 cppreference example)

如果你想折磨一些字符串流,你可以使用 protected 接口(interface)访问缓冲区:

#include <iostream>
#include <sstream>
#include <vector>

struct my_stringbuf : std::stringbuf {
    const char* my_str() const { return pbase(); } // pptr might be useful too
};

int main()
{
    std::vector<float> v = {1.1, -3.4, 1/7.0};
    my_stringbuf buf;
    std::ostream ss(&buf);
    for(unsigned int i=0; i < v.size(); ++i)
        ss << v[i] << ' ';
    ss << std::ends;
    std::cout << buf.my_str() << '\n';
}

直接访问自动调整大小的输出流缓冲区的标准 C++ 方法由 std::ostrstream 提供,在 C++98 中已弃用,但仍是标准 C++14 并且还在增加。

#include <iostream>
#include <strstream>
#include <vector>

int main()
{
    std::vector<float> v = {1.1, -3.4, 1/7.0};
    std::ostrstream ss;
    for(unsigned int i=0; i < v.size(); ++i)
        ss << v[i] << ' ';
    ss << std::ends;
    const char* buffer = ss.str(); // direct access!
    std::cout << buffer << '\n';
    ss.freeze(false); // abomination
}

但是,我认为最干净(也是最快)的解决方案是 boost.karma

#include <iostream>
#include <string>
#include <vector>
#include <boost/spirit/include/karma.hpp>
namespace karma = boost::spirit::karma;
int main()
{
    std::vector<float> v = {1.1, -3.4, 1/7.0};
    std::string s;
    karma::generate(back_inserter(s), karma::double_ % ' ', v);
    std::cout << s << '\n'; // here's your string
}

关于c++ - 将字符串移出 std::ostringstream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26266525/

相关文章:

c++ - 我可以在带有值初始化的 header 中使用 static const float

c++ - 使用 auto 访问类的私有(private)结构

c++ - 如何为运算符正确编写 R 值重载

c++ - 编译器生成的 Action 的实现

c++ - 如何使用 C++11 move 语义从函数返回 std::vector?

c++ - XCode 链接器错误、 undefined reference 、模板、Const

c++ - 在 cmake 中混合 C 和 C++ 源代码

c++ - vector C++ 的独特算法

c++ - 链接列表 - 几乎完成,但在某处仍然存在小问题。需要帮助

c++ - rethrow_exception 真的可以抛出相同的异常对象,而不是一个拷贝吗?