A better way of formatting strings?

Discussion in 'C++' started by Ricky65, Mar 24, 2011.

  1. Ricky65

    Ricky65 Guest

    I was thinking about string formatting after reading this article by
    Herb Sutter here:
    http://www.gotw.ca/publications/mill19.htm

    I thought to myself "Why haven't they overloaded the << operator for
    the basic_string class?" like with the iostream. I don't think I'm the
    first to have thought of this. I assume performance problems are the
    reason this is not done.

    This would eliminate the need to make a temporary variable to hold the
    formatted data like a stringstream does and the problems with the
    sprintf family. I know a lot of people shun stringstreams because they
    are unacceptably slow in some cases.

    For example, we could do something like this:
    int cat_len = 120;
    int mouse_len = 29;

    std::string myformattedstring << "The cat is " << a << "cm tall and
    the mouse is " << b << "cm tall.";

    As you can see, this would format directly to the string. This would
    be both type safe and length safe and the programmer wouldn't have to
    allocate a temporary variable for a stream. However, I'm not sure how
    efficient it would be. I'm intrigued to know if this can be done and
    and if not, the reasons why.

    Thanks

    Ricky Marcangelo
    Ricky65, Mar 24, 2011
    #1
    1. Advertising

  2. Ricky65

    Ricky65 Guest

    sorry, brainstorm. a and b should be cat_len and mouse_len
    respectively.
    Ricky65, Mar 24, 2011
    #2
    1. Advertising

  3. On 3/24/2011 10:38 AM, Ricky65 wrote:
    > I was thinking about string formatting after reading this article by
    > Herb Sutter here:
    > http://www.gotw.ca/publications/mill19.htm
    >
    > I thought to myself "Why haven't they overloaded the<< operator for
    > the basic_string class?" like with the iostream. I don't think I'm the
    > first to have thought of this. I assume performance problems are the
    > reason this is not done.
    >
    > This would eliminate the need to make a temporary variable to hold the
    > formatted data like a stringstream does and the problems with the
    > sprintf family. I know a lot of people shun stringstreams because they
    > are unacceptably slow in some cases.
    >
    > For example, we could do something like this:
    > int cat_len = 120;
    > int mouse_len = 29;
    >
    > std::string myformattedstring<< "The cat is "<< a<< "cm tall and
    > the mouse is "<< b<< "cm tall.";


    This syntax is invalid. You either declare an object (and initialize
    it) or manipulate it using operator<<. You can't do both in the same
    statement.

    > As you can see, this would format directly to the string. This would
    > be both type safe and length safe and the programmer wouldn't have to
    > allocate a temporary variable for a stream. However, I'm not sure how
    > efficient it would be. I'm intrigued to know if this can be done and
    > and if not, the reasons why.


    It cannot, see above.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Mar 24, 2011
    #3
  4. Ricky65

    Ricky65 Guest

    On Mar 24, 2:52 pm, Victor Bazarov <> wrote:
    > On 3/24/2011 10:38 AM, Ricky65 wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > I was thinking about string formatting after reading this article by
    > > Herb Sutter here:
    > >http://www.gotw.ca/publications/mill19.htm

    >
    > > I thought to myself "Why haven't they overloaded the<<  operator for
    > > the basic_string class?" like with the iostream. I don't think I'm the
    > > first to have thought of this. I assume performance problems are the
    > > reason this is not done.

    >
    > > This would eliminate the need to make a temporary variable to hold the
    > > formatted data like a stringstream does and the problems with the
    > > sprintf family. I know a lot of people shun stringstreams because they
    > > are unacceptably slow in some cases.

    >
    > > For example, we could do something like this:
    > > int cat_len = 120;
    > > int mouse_len = 29;

    >
    > > std::string myformattedstring<<  "The cat is "<<  a<<  "cm tall and
    > > the mouse is "<<  b<<  "cm tall.";

    >
    > This syntax is invalid.  You either declare an object (and initialize
    > it) or manipulate it using operator<<.  You can't do both in the same
    > statement.
    >
    > > As you can see, this would format directly to the string. This would
    > > be both type safe and length safe and the programmer wouldn't have to
    > > allocate a temporary variable for a stream. However, I'm not sure how
    > > efficient it would be. I'm intrigued to know if this can be done and
    > > and if not, the reasons why.

    >
    > It cannot, see above.
    >
    > V
    > --
    > I do not respond to top-posted replies, please don't ask


    Sorry, I meant

    std::string myformattedstring;

    myformattedstring << "The cat is " << a << "cm tall and
    the mouse is " << b << "cm tall.";
    Ricky65, Mar 24, 2011
    #4
  5. On 24 mar, 15:38, Ricky65 <> wrote:
    > I was thinking about string formatting after reading this article by
    > Herb Sutter here:http://www.gotw.ca/publications/mill19.htm
    >
    > I thought to myself "Why haven't they overloaded the << operator for
    > the basic_string class?" like with the iostream.


    Who is "they" ? The standard committee ?

    > I don't think I'm the
    > first to have thought of this. I assume performance problems are the
    > reason this is not done.


    Doing so would shun formating facilities.

    The language definition is geared toward general case. If you have
    specific needs, you are expected to roll your own. This avoid
    cluttering the standard with use cases that you can recode or that
    libraries can provide.

    > This would eliminate the need to make a temporary variable to hold the
    > formatted data like a stringstream does and the problems with the
    > sprintf family. I know a lot of people shun stringstreams because they
    > are unacceptably slow in some cases.


    I expect that using a temporary stringstream is more efficient than
    appending into a string.

    >
    > For example, we could do something like this:
    > int cat_len = 120;
    > int mouse_len = 29;
    >
    > std::string myformattedstring << "The cat is " << a << "cm tall and
    > the mouse is " << b << "cm tall.";
    >
    > As you can see, this would format directly to the string. This would
    > be both type safe and length safe and the programmer wouldn't have to
    > allocate a temporary variable for a stream. However, I'm not sure how
    > efficient it would be. I'm intrigued to know if this can be done and
    > and if not, the reasons why.


    As you wrote it, it is impossible: you cannot mix variable definition
    and initialization this way.

    Something possible is:
    std::string myformattedstring = string_formater()<<"The cat is "
    <<...;

    Some very fast formating constructs based on template can be designed
    this way ( especially if the maximum size of each element can be
    computed beforehand). But they have some limitations.

    If you want to see an example, you can lookup the FastFormat library
    from Matthew Wilson and its shims technique.


    Concerning the form, I'd prefer:
    std::string myformattedstring = ("The cat is ",fmt::_1,"cm tall and
    the mouse is ",fmt::_2,"cm tall.")
    , cat_len, mouse_len;

    --
    Michael
    Michael Doubez, Mar 24, 2011
    #5
  6. On 3/24/2011 11:04 AM, Ricky65 wrote:
    > On Mar 24, 2:52 pm, Victor Bazarov<> wrote:
    >> On 3/24/2011 10:38 AM, Ricky65 wrote:
    >>
    >>
    >>
    >>
    >>
    >>
    >>
    >>
    >>
    >>> I was thinking about string formatting after reading this article by
    >>> Herb Sutter here:
    >>> http://www.gotw.ca/publications/mill19.htm

    >>
    >>> I thought to myself "Why haven't they overloaded the<< operator for
    >>> the basic_string class?" like with the iostream. I don't think I'm the
    >>> first to have thought of this. I assume performance problems are the
    >>> reason this is not done.

    >>
    >>> This would eliminate the need to make a temporary variable to hold the
    >>> formatted data like a stringstream does and the problems with the
    >>> sprintf family. I know a lot of people shun stringstreams because they
    >>> are unacceptably slow in some cases.

    >>
    >>> For example, we could do something like this:
    >>> int cat_len = 120;
    >>> int mouse_len = 29;

    >>
    >>> std::string myformattedstring<< "The cat is "<< a<< "cm tall and
    >>> the mouse is "<< b<< "cm tall.";

    >>
    >> This syntax is invalid. You either declare an object (and initialize
    >> it) or manipulate it using operator<<. You can't do both in the same
    >> statement.
    >>
    >>> As you can see, this would format directly to the string. This would
    >>> be both type safe and length safe and the programmer wouldn't have to
    >>> allocate a temporary variable for a stream. However, I'm not sure how
    >>> efficient it would be. I'm intrigued to know if this can be done and
    >>> and if not, the reasons why.

    >>
    >> It cannot, see above.
    >>
    >> V
    >> --
    >> I do not respond to top-posted replies, please don't ask

    >
    > Sorry, I meant
    >
    > std::string myformattedstring;
    >
    > myformattedstring<< "The cat is "<< a<< "cm tall and
    > the mouse is "<< b<< "cm tall.";


    That is *usually* done with stringstreams:

    std::eek:stringstream myformattedstream;
    myformattedstream << "The cat it in the hat";

    std::string myformattedstring = myformattedstream.str();

    There is no need to pollute std::string with the functionality that
    already exists in another class.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Mar 24, 2011
    #6
  7. On 24 mar, 16:49, Leigh Johnston <> wrote:
    > On 24/03/2011 15:34, Michael Doubez wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > On 24 mar, 15:38, Ricky65<>  wrote:
    > >> I was thinking about string formatting after reading this article by
    > >> Herb Sutter here:http://www.gotw.ca/publications/mill19.htm

    >
    > >> I thought to myself "Why haven't they overloaded the<<  operator for
    > >> the basic_string class?" like with the iostream.

    >
    > > Who is "they" ? The standard committee ?

    >
    > >> I don't think I'm the
    > >> first to have thought of this. I assume performance problems are the
    > >> reason this is not done.

    >
    > > Doing so would shun formating facilities.

    >
    > > The language definition is geared toward general case. If you have
    > > specific needs, you are expected to roll your own. This avoid
    > > cluttering the standard with use cases that you can recode or that
    > > libraries can provide.

    >
    > >> This would eliminate the need to make a temporary variable to hold the
    > >> formatted data like a stringstream does and the problems with the
    > >> sprintf family. I know a lot of people shun stringstreams because they
    > >> are unacceptably slow in some cases.

    >
    > > I expect that using a temporary stringstream is more efficient than
    > > appending into a string.

    >
    > >> For example, we could do something like this:
    > >> int cat_len = 120;
    > >> int mouse_len = 29;

    >
    > >> std::string myformattedstring<<  "The cat is "<<  a<<  "cm tall and
    > >> the mouse is "<<  b<<  "cm tall.";

    >
    > >> As you can see, this would format directly to the string. This would
    > >> be both type safe and length safe and the programmer wouldn't have to
    > >> allocate a temporary variable for a stream. However, I'm not sure how
    > >> efficient it would be. I'm intrigued to know if this can be done and
    > >> and if not, the reasons why.

    >
    > > As you wrote it, it is impossible: you cannot mix variable definition
    > > and initialization this way.

    >
    > > Something possible is:
    > > std::string myformattedstring = string_formater()<<"The cat is"
    > > <<...;

    >
    > > Some very fast formating constructs based on template can be designed
    > > this way ( especially if the maximum size of each element can be
    > > computed beforehand). But they have some limitations.

    >
    > > If you want to see an example, you can lookup the FastFormat library
    > > from Matthew Wilson and its shims technique.

    >
    > > Concerning the form, I'd prefer:
    > > std::string myformattedstring = ("The cat is ",fmt::_1,"cm tall and
    > > the mouse is ",fmt::_2,"cm tall.")
    > >                                           , cat_len, mouse_len;

    >
    > That does not lend itself to well to localization; consider boost.format
    > instead.


    It depends on what you want to achieve. Boost.Format is great for
    having complex format (event tabulation IIRC) while others won't need
    the internationalisation/localisation but prefer high speed (like in
    logging or feeding another program).

    See:
    http://accu.org/index.php/journals/1539

    --
    Michael
    Michael Doubez, Mar 24, 2011
    #7
  8. Ricky65

    James Kanze Guest

    On Mar 24, 3:49 pm, Leigh Johnston <> wrote:
    > On 24/03/2011 15:34, Michael Doubez wrote:


    [...]
    > > Concerning the form, I'd prefer:
    > > std::string myformattedstring = ("The cat is ",fmt::_1,"cm tall and
    > > the mouse is ",fmt::_2,"cm tall.")
    > > , cat_len, mouse_len;


    I'd be interested in seeing how that could be implemented
    without varargs, and the resulting loss of type safety.

    > That does not lend itself to well to localization; consider boost.format
    > instead.


    boost::format solves one small aspect of localization, but in
    practice, it's rarely enough. I had a class which did the same
    thing, long before there was boost, and I gradually stopped
    maintaining it, because it didn't solve any real problems
    satisfactorily. (And unlike boost::format, it didn't really
    work with manipulators. And you really want user defined
    manipulators to define semantic markup.) As soon as more than
    one language is involved, you almost always have to have a
    separate dll, with specially written code, for each language.

    --
    James Kanze
    James Kanze, Mar 26, 2011
    #8
  9. Ricky65

    Ricky65 Guest

    On Mar 25, 7:06 am, Paavo Helde <> wrote:
    > Ricky65 <> wrote in news:4f8cb849-5b91-4f44-939c-
    > :
    >
    > > Sorry, I meant

    >
    > > std::string myformattedstring;

    >
    > > myformattedstring << "The cat is " << a << "cm tall and
    > > the mouse is " << b << "cm tall.";

    >
    > No problem if you really want this, just add a little helper function.
    > Note that this essentially duplicates stringstream functionality for
    > another class (std::string) actually meant for other purposes.
    >
    > #include <iostream>
    > #include <string>
    > #include <sstream>
    >
    > template<typename T>
    > std::string& operator<<(std::string& s, const T& x) {
    >    std::eek:stringstream os;
    >    os << x;
    >    s += os.str();
    >    return s;
    >
    > }
    >
    > int main() {
    >    std::string myformattedstring;
    >    int a = 10;
    >    double b = 3.5;
    >    myformattedstring << "The cat is " << a <<
    >        "cm tall and the mouse is " << b << "cm tall.";
    >    std::cout << myformattedstring << "\n";
    >
    >
    >
    >
    >
    >
    >
    > }


    Thanks for this example. This was what I had in mind in my original
    post. However, am I right in saying that this wouldn't be any faster
    than using normal stringstream? If so, I may as well stick to good old
    stringstreams.
    Ricky65, Mar 28, 2011
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Brat
    Replies:
    7
    Views:
    376
    Marc 'BlackJack' Rintsch
    Sep 6, 2006
  2. Ben

    Strings, Strings and Damned Strings

    Ben, Jun 22, 2006, in forum: C Programming
    Replies:
    14
    Views:
    757
    Malcolm
    Jun 24, 2006
  3. Peter Bencsik
    Replies:
    2
    Views:
    828
  4. Paul Rubin
    Replies:
    5
    Views:
    417
    Hendrik van Rooyen
    Aug 6, 2009
  5. Replies:
    2
    Views:
    52
    Mark H Harris
    May 13, 2014
Loading...

Share This Page