A version of operator<< that returns ostringstream instead of ostream I always thought it would be handy to be able to write:

const std::string s = (std::ostringstream() &lt;&lt; "hi" &lt;&lt; 0).str();


This doesn't work in C++ by default because operator&lt;&lt; returns the ostringstream as a ostream, which obviously doesn't have the str() member.

I was pleasantly surprised though to discover that this can be done in C++11:

#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;

template &lt;typename CharT, typename traits, typename T&gt;
std::basic_ostringstream&lt;CharT,traits&gt;&amp;&amp; operator&lt;&lt;(std::basic_ostringstream&lt;CharT,traits&gt;&amp;&amp; out, const T&amp; t) {
  static_cast&lt;std::basic_ostream&lt;CharT,traits&gt;&amp;&gt;(out) &lt;&lt; t;
  return std::move(out);
}

int main() {
  const std::string s = (std::ostringstream() &lt;&lt; "hi" &lt;&lt; 0).str();
  std::cout &lt;&lt; s &lt;&lt; std::endl;
}


It needs rvalue references and move semantics to bind the temporary to a reference here.


Is there a good reason why this isn't provided by the standard library by default? Is it an oversight? Making this idiom legal code seems like it might offer a number of benefits.
In my local C++11 project, I provide some "utility" code. Is there any reason why I shouldn't include this and use it widely?


How about the more generic version:

template &lt;typename S, typename T, class = typename
               std::enable_if&lt;std::is_base_of&lt;std::basic_ostream&lt;typename S::char_type,typename S::traits_type&gt;, S&gt;::value&gt;::type&gt;
S&amp;&amp; operator&lt;&lt;(S&amp;&amp; out, const T&amp; t) {
  static_cast&lt;std::basic_ostream&lt;typename S::char_type,typename S::traits_type&gt;&amp;&gt;(out) &lt;&lt; t;
  return std::move(out);
}
Bjarne gives a pretty succinct description of why this (and many similar) features aren't in the standard. He points out that virtually everybody who talks to him about C++ has essentially the same thing to say: "C++ is way to big and way too complex. You should really work at making it a lot smaller and simpler. Oh, but while you're at it, you should add this one really great feature I thought of"

It kind of reminds me of things I've seen about how questions of political polls can be/ are phrased. If I ask: "Do you think this country should do more to [increase jobs | help the needy | etc.]?" I can count on a large majority of people saying "yes." If I ask "Do you think we should raise taxes by X%?", I can count on an equally large majority saying "No". I can give nearly a guaranteed outcome from my poll just by choosing whether to ask about the hoped-for outcome or the cost.

Bottom line: Each feature you add has a cost, and focusing on the outcome doesn't remove the cost. To design a usable language/library, you need to restrict features to the few that provide the greatest positive outcome for the lowest cost. In the case of the C++ committee, they've been pretty clear about a few things, and one is that most new features will barely be considered at all unless they enable fairly substantial improvements in code that uses the new feature and have extremely minimal cost, especially in terms of breaking any existing code.