2

I'd like to understand why writing this

static_cast<std::ostringstream*>( &(std::ostringstream() << speed.x) )->str();

makes a string, but not this

(std::ostringstream() << speed.x).str();?

in fact the latter doesn't even compile...

I find this static_cast<foo*>&foo to be quite weird.

can you give me good examples in which case it's good practice to do so?

Sheed
  • 577
  • 4
  • 18
  • 1
    The reason you get an error is because the result of `(std::ostringstream() << speed.x)` is what the `operator<<` function returns, and it returns a reference to a `std::ostream`, which of course doesn't have a `str()` member function. In short, it's not really possible to do it as a one-liner. Why can't you use e.g. [`std::to_string`](http://en.cppreference.com/w/cpp/string/basic_string/to_string) or [Boost lexical cast](http://www.boost.org/doc/libs/1_65_1/doc/html/boost_lexical_cast.html)? – Some programmer dude Sep 30 '17 at 08:40
  • Tks for the answer, I tried `std::to_string`, but for an unknown reason codeblocks doesn't recognize it as a part of std even though I clicked -std=c++11. Also, if as you say `<< operator` sends a reference to ostream, why would I need to use `&` again? Isn't it redundant? – Sheed Sep 30 '17 at 08:47
  • 1
    You can cast a reference - no need to use pointers `static_cast( std::ostringstream() << x ).str() ` – Artemy Vysotsky Sep 30 '17 at 09:11

1 Answers1

1

The the expression std::ostringstream() << speed.x actually invokes the operator<<(double) on the underlying base class std::ostream interface.

The return type of std::ostream::operator<<(double) is std::ostream& which means you're trying to invoke the member function std::ostream::str() which of course does not exist. That method is on the derived class.

This is why the static_cast is necessary in this use case.

You could also write:

static_cast<std::ostringstream&>(std::ostringstream() << speed.x).str();

or since c++11

std::to_string(speed.x);

or in previous versions, you could write your own, less cryptic function which will do the same thing in a more maintainable way with no overhead.

std::string to_string(double x)
{
    std::ostringstream ss;
    ss << x;
    return ss.str();
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • if return type is `std::ostream&`, isn't it redundant to use & again? I mean this part: `&(std::ostringstream() << speed.x)`, isn't it like writing `&&foo` which is wrong, no? – Sheed Sep 30 '17 at 11:40
  • @BenoîtLu if you wrote `static_cast` then you'd be trying to take a copy of the `std::ostream`, which would result in a compile error. – Richard Hodges Sep 30 '17 at 11:53
  • Hmm... Are we clear that `std::ostream` is different than `std::ostream&` ? Return type of `std::ostringstream() <<` as you told me is `std::ostream&`, and in my snippet of code I have `static_cast&(std::ostream&)`. forget the static_cast, my problem is that we're doing `&(std::ostream&)`, so basically "getting a reference of a reference", that's what's bothering me, but it's working nonetheless. I hope I clarified my problem. – Sheed Sep 30 '17 at 12:16
  • @BenoîtLu Careful. `&(x)` where x is a reference is taking the address of a reference, which is the same as taking the address of the object itself. It's not taking a reference of a reference. You could write `std::addressof(std::ostringstream() << speed.x)` – Richard Hodges Sep 30 '17 at 13:12