Possible bug in ostream_iterator

John Schmerge jbschmerge@gmail.com
Wed Dec 11 06:41:00 GMT 2013


Hey guys,

  I ran into a curiosity that is causing an error for me with both gcc
4.7.x and 4.8.1 (I haven't tried with 4.8.2 yet):

<example_code>

#include <iostream>
#include <iterator>
#include <string>
#include <utility>

using EnvPair = std::pair<const std::string, std::string>;

// the function signature here is adapted from the output operator
from std::complex...
// most likely the same issues would exist with that class
template <class CharT, class Traits>
std::basic_ostream<CharT, Traits> &
operator << (std::basic_ostream<CharT, Traits> & out, const EnvPair & ep)
{
    out << std::get<0>(ep) << "=" << std::get<1>(ep);
    return out;
}

int main(int argc, char ** argv)
{
    EnvPair ep{ "foo", "bar" };

    // No problem
    std::cout << ep << '\n' << std::string(70, '-') << std::endl;

    std::ostream_iterator<EnvPair> out_iter(std::cout, "\n");

#ifdef BROKEN
    out_iter = ep;
#endif

    return 0;
}
</example_code>

What i get when the output iterator assignment is enabled is the
following error:

In file included from /usr/include/c++/4.8/iterator:66:0,
                 from prog.cpp:2:
/usr/include/c++/4.8/bits/stream_iterator.h: In instantiation of
‘std::ostream_iterator<_Tp, _CharT, _Traits>&
std::ostream_iterator<_Tp, _CharT, _Traits>::operator=(const _Tp&)
[with _Tp = std::pair<const std::basic_string<char>,
std::basic_string<char> >; _CharT = char; _Traits =
std::char_traits<char>]’:
prog.cpp:26:11:   required from here
/usr/include/c++/4.8/bits/stream_iterator.h:198:13: error: cannot bind
‘std::ostream_iterator<std::pair<const std::basic_string<char>,
std::basic_string<char> > >::ostream_type {aka
std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
  *_M_stream << __value;
             ^
In file included from /usr/include/c++/4.8/iostream:39:0,
                 from prog.cpp:1:
/usr/include/c++/4.8/ostream:602:5: error:   initializing argument 1
of ‘std::basic_ostream<_CharT, _Traits>&
std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&)
[with _CharT = char; _Traits = std::char_traits<char>; _Tp =
std::pair<const std::basic_string<char>, std::basic_string<char> >]’
     operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
     ^

It appears that the ostream& operator << (ostream &&, const T &)
wrappers in iostream are interfering with user defined << overloads.

As for why '*_M_stream' is forcing the rvalue reference, I'm not
knowledgeable enough about the precedence rules for the new reference
type to comment on whether this is a library bug or a compiler issue.

Any guidance someone might give to me would be of help, or if you'd
like me to write up a bug report, please point me to the appropriate
place.

Thanks,
John



More information about the Libstdc++ mailing list