paercebal
paercebal

Reputation: 83404

c++ overloading operator << for std::string

I'm just now seeing another naive C++ code using sprintf to append C builtins into an array of chars, and I guess enough is enough.

I could help providing with simple, lightweight, appending and non-formatting functions for std::string, but as it would be check-in-ed into the team's common code, I want it to be perfect, so I need some advice on the interface of this feature (i.e. not on the actual implementation).

The following could be possible (I did not test it, it's just a hunch):

  1. Overloading the "+=" operator (probably in another namespace than std or global)
  2. Overloading the "<<" operator (again, in another namespace)
  3. Providing non-operator non-member functions (I guess, again in another namespace)
  4. Another easy solution I did not see?

What would be the pros and the cons of each solution (I have a preference for "+=", or even "<<") ?

Notes

.

// sprintf-like code with a char[] buffer:
sprintf(buffer, "%d", myDouble) ;

// stream-like code with a std::string buffer:
std::stringstream str ;
str << myDouble ;
buffer = str.str() ;

// example of desired code with a std::string buffer:
buffer += myDouble ;

Upvotes: 3

Views: 6510

Answers (4)

rve
rve

Reputation: 6055

  1. What about boost::format ? Then you can write:

    std::string first("world");
    std::string s = (boost::format("hello %1%") % first).str();
    
  2. Or create a wrapper class which you can use like so:

    int i(2);
    std::string s = (Format() + "Hello " + first + " " + i).str();
    

    And Format() something like (without boost) :

    class Format
    {
        public:
            template <typename T>
            Format &operator+(const T& v) {
                m_sstr << v; 
                return *this;
            };
            const std::string &str() const { return m_sstr.str(); };
        private:
            std::stringstream m_sstr;
    };
    

Upvotes: 3

mirk
mirk

Reputation: 5530

C++11 comes with an overloaded set of std::to_string functions.

example prototype:

std::string to_string( int value );

They are allowed to be overriden by the user (in C++11). You would need your own namespace for now.

You could implement your own set for the types of your choice. It would make for future-proof code.

you would use the code as:

std::string s;
s+=std::to_string(1);

Upvotes: 3

Matthew Walton
Matthew Walton

Reputation: 9969

boost::lexical_cast provides a potential model for you here - write a function that can handle any of the datatypes you need, turn them into a string in the appropriate format for your purposes (and you can optimise that as much as you need to/are able to), and return them for use with operator+(string, string).

Specialise the function per type either with normal overloading or template specialisations according to your preference. lexical_cast uses templates so it can handle absolutely anything via whatever stream operators happen to be defined, but your use case is far narrower than this, and so you definitely can get some more performance out of it.

Upvotes: 0

kol
kol

Reputation: 28728

I would use ostringstream and stream manipulators to replace sprintf. It's not worth reinventing the wheel.

Upvotes: 3

Related Questions