将对象直接流入std :: string

时间:2016-08-03 20:21:38

标签: c++ string

鉴于某种类型是可流式的:

struct X {
    int i;

    friend std::ostream& operator<<(std::ostream& os, X const& x) {
        return os << "X(" << x.i << ')';
    }
};

我想将其附加到std::string。我可以这样实现:

void append(std::string& s, X const& x) {
    std::ostringstream os;
    os << x;
    s.append(os.str());
}

但这似乎很蹩脚,因为我将数据写入一个流只是为了将其附加到另一个流上而分配一个新字符串。有更直接的路线吗?

4 个答案:

答案 0 :(得分:15)

这可以通过新类型streambuf来解决(请参阅Standard C++ IOStreams and Locales: Advanced Programmer's Guide and Reference)。

以下是它的外观草图:

unitsPerInches=[0 0 15 15];
aFig=figure();
a1=subplot(1,2,1);
a2=subplot(1,2,2);

bFig=figure();
b1=subplot(1,2,1);
b2=subplot(1,2,2);

for counter=1:2;
    if counter==1
        set(a1, 'Position', unitsPerInches); % affect only position of a1
    end
    subplot(1,2,counter);    
    imagesc(rand(3));
    drawnow    

    subplot(1,2,counter);    
    imagesc(rand(3));
    drawnow    
end

一旦你充实了这里的细节,你可以按如下方式使用它:

#include <streambuf>

class existing_string_buf : public std::streambuf
{
public:
    // Store a pointer to to_append.
    explicit existing_string_buf(std::string &to_append); 

    virtual int_type overflow (int_type c) {
        // Push here to the string to_append.
    }
};

现在您只需写信至#include <iostream> std::string s; // Create a streambuf of the string s existing_string_buf b(s); // Create an ostream with the streambuf std::ostream o(&b); ,结果应显示为o的附加内容。

s

修改

正如@rustyx正确指出的那样,为了提高性能,需要覆盖// This will append to s o << 22;

完整示例

以下打印xsputn

22

答案 1 :(得分:2)

你可以写一个std :: string cast操作符:

struct X {
int i;

friend std::ostream& operator<<(std::ostream& os, X const& x) {
    os << "X(" << x.i << ')';
    return os;
}

operator std::string() {
    return std::string("X(") + std::to_string(x.i) + ")";
}

};

然后,您可以简单地将其附加到std :: string:

X myX;
myX.i = 2;
std::string s("The value is ");
s.append(myX); //myX is cast into the string "X(2)"

答案 2 :(得分:1)

在这个具体案例中,我只是遵循KISS原则:

struct X {
    int i;

    std::string toString() const {
        return "X(" + std::to_string(i) + ")";
    }
};

用法:

string += x.toString();
std::cout << x.toString();

operator<<(std::ostream&, …)并不适合通用字符串转换,所以如果这就是你所追求的,那么toString类型的方法/自由函数要好得多。如果您需要std::cout << x,您可以轻松实现operator<<,只需致电toString

答案 3 :(得分:-1)

由于原始字符串可能只对现有分配足够大,因此您最希望的是格式化要在流中追加一次的所有内容,然后按照示例中的结果附加结果。

如果您打算经常执行这些追加,我认为std :: string是手头问题的错误类型。我建议直接使用std :: ostringtream而不是std :: string,只在需要最终结果时才转换为字符串。