3
votes

I am creating a custom ostream class which is briefly exposed in the following snippet. I would like to be able to use std::endl but the compiler does not let me. I don’t understand why.

#include <iostream> 

struct Bar
{
};

template <typename T>
struct Foo
{
};

template <typename T, typename U>
Foo<T>& operator<<(Foo<T>& _foo, U&&)
{
  return _foo;
}

int main()
{
  Foo<Bar> f;
  f << "aa" << std::endl;
}

The error gcc 4.7.1 gives me is:

main.cpp:21:21: error: no match for ‘operator<<’ in ‘operator<< ((* & f), (*"aa")) << std::endl’ main.cpp:21:21: note: candidates are: main.cpp:13:9: note: template Foo& operator<<(Foo&, U&&) main.cpp:13:9: note: template argument deduction/substitution failed: main.cpp:21:21: note:
couldn't deduce template parameter ‘U’

Why can’t it deduce parameter U? Shouldn’t this be typeof(std::endl) ?

2
We have decltype and typeid for that.chris
@oldrinb some operator from java. I meant decltype .qdii
Why do you have a custom ostream? Most of the time people think they want a custom ostream, a custom streambuf will do what they want with a lot less work.Jerry Coffin
@qdii that's not true either, though... are you thinking of instanceof? :-)obataku
@oldrinb ah yea :) The bright side is that I never use any of them, I suppose.qdii

2 Answers

5
votes

Since std::endl is

namespace std {
template <class charT, class traits>
basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);
}

Your class is not derived from basic_ostream, so it cannot work.

And basic_ostream has

basic_ostream<charT,traits>& operator<<
(basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&))

for works with manipulators like std::endl.

3
votes

Note, that there is rarely a need to use the template approach nor is there a good use of deriving from std::ostream for a different purpose than convenient initialization of a std::ostream with a custom std::streambuf. To create new sources or targets to read from or write to, you derive from std::streambuf. For a stream writing you typically overwrite std:;streambuf::overflow() and std::streambuf::sync().