1

If we want to construct a complex string, say like this: "I have 10 friends and 20 relations" (where 10 and 20 are values of some variables) we can do it like this:

std::ostringstream os;
os << "I have " << num_of_friends << " friends and " << num_of_relations << " relations";

std::string s = os.str();

But it is a bit too long. If in different methods in your code you need to construct compound strings many times you will have to always define an instance of std::ostringstream elsewhere.

Is there a shorter way of doing so just in one line?

I created some extra code for being able to do this:

struct OstringstreamWrapper
{
     std::ostringstream os;
};

std::string ostream2string(std::basic_ostream<char> &b)
{
     std::ostringstream os;
     os << b;
     return os.str();
}

#define CreateString(x) ostream2string(OstringstreamWrapper().os << x)

// Usage:
void foo(int num_of_friends, int num_of_relations)
{
     const std::string s = CreateString("I have " << num_of_friends << " and " << num_of_relations << " relations");
}

But maybe there is simpler way in C++ 11 or in Boost?

2

2 Answers 2

3
#include <string>
#include <iostream>
#include <sstream>

template<typename T, typename... Ts>
std::string CreateString(T const& t, Ts const&... ts)
{
    using expand = char[];

    std::ostringstream oss;
    oss << std::boolalpha << t;
    (void)expand{'\0', (oss << ts, '\0')...};
    return oss.str();
}

void foo(int num_of_friends, int num_of_relations)
{
    std::string const s =
        CreateString("I have ", num_of_friends, " and ", num_of_relations, " relations");
    std::cout << s << std::endl;
}

int main()
{
    foo(10, 20);
}

Online Demo

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, that's great, I was just hoping there is a syntax using <<.
@user429775 : Not that I can think of, at least not without an ugly cast involved. In any case, this is implemented in terms of operator<<, so that's still all you need for your types to work here.
I have posted a question about how exactly this code works, here: stackoverflow.com/q/35232729/1025391
1

You could use Boost.Format:

#include <iostream>
#include <boost/format.hpp>

using boost::format;

int main()
{
    std::cout << boost::format("I have %1% friends and %2% relations")
        % num_of_friends % num_of_relations; 
}

3 Comments

Well, that's nice, but if you want to change one parameter, you need to change in two places: in %1% and in % num_of_friends. Also if you just print to stdout using << and want to change it to be saved in string, you have to change it completely using %.
You can use %s instead of numbered parameters if you want.
@user429775 If you want to change your “print to std::cout” code to “save it into a string” code with as minimal edits as possible, the solution is to use a std::ostringstream as shown in your question. What's the point?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.