Appending an integer to a string

I feel I am forgetting something basic - given:

 
void log(const string & _str){...}


what is an elegant way to write:

1
2
int n = geterr();
log("Error code is " + n);


I often use macros for logging, in which case I can do something like

 
LOG("Error code is " << n)


but I feel there should be a way to do this in c++03 without this type of hack. I made an overload of log taking a ss and tried log(stringstream("Error code is") << n), but operator<< returns an ostream&, not a stringstream&, so without casting this won't work either.

Thoughts?
Last edited on
*not my code*
1
2
3
4
5
6
7
8
9
10
11
12
class Formatter
{
public:
    template<class Val> Formatter& operator<<(const Val& val)
    {
        ss_ << val;
        return * this;
    }
    operator string () const { return ss_.str().c_str(); }
private:
    std::stringstream ss_;
};

usage:
logger(Formatter() << "The variable is: " << variable);
Use a function to log:

1
2
3
4
5
6
7
template < typename T > std::ostream& do_log( const T& v , std::ostream& stm = std::clog )
{ return stm << v ; }

// and then
// ...
    do_log( "Error code is " ) << std::setw(5) << std::setfill('0') << 123 << std::endl ;
// ...  


Or, use a class to log:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct logger
{
    explicit logger( std::ostream& s = std::clog ) : stm(s) {}

    template < typename T > logger& operator << ( const T& v )
    { std::cout << v  ; return *this ; }

    logger& operator<< ( std::ostream& (*fn)( std::ostream& ) )
    { std::cout << fn ;  return *this ; }

    logger& operator<< ( std::ios& (*fn)( std::ios& ) )
    { std::cout << fn ; return *this ; }

     logger& operator<< ( std::ios_base& (*fn)( std::ios_base& ) )
    { std::cout << fn ; return *this ; }

    private: std::ostream& stm ;
};

// and then
// ...
    logger log ;
    log << "Error code is " << std::setw(5) << std::setfill('0') << 123 << std::endl ;
// ...  
Last edited on
Topic archived. No new replies allowed.