Template type deduction for stream manipulators

c++, iostream, manipulators, templates

Solution

`endl` is a manipulator, i.e. it's an unresolved function type. There are several overloads, and the type deduction is unable to decide which one you want.

More specificly, here's what `endl` looks like (in GNU libc++):

/**
 *  @brief  Write a newline and flush the stream.
 *
 *  This manipulator is often mistakenly used when a simple newline is
 *  desired, leading to poor buffering performance.  See
 *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch25s02.html
 *  for more on this subject.
*/
template<typename _CharT, typename _Traits>
  inline basic_ostream<_CharT, _Traits>&
  endl(basic_ostream<_CharT, _Traits>& __os)
  { return flush(__os.put(__os.widen('\n'))); }

Updated So, the problem is, the compiler cannot deduce which instance of `endl` you would be passing (it's an unresolved overload). You might work around this by doing a `static_cast<ostream&(*)(ostream&)>(endl)` instead.

Of course, that's not convenient. Here's a simple fix: http://liveworkspace.org/code/2F2VHe$1

#include <iostream>
using std::cout;
using std::endl;

class Foo : public std::ostream
{
    public:
        template<typename T>
        Foo& operator<<(T&& t) {
            cout << std::forward<T>(t);
            return *this;
        }

        typedef std::ostream& (manip)(std::ostream&);

        Foo& operator<<(manip& m) {
            cout << m;
            return *this;
        }
};

int main() {
    Foo foo;
    foo << "Hello World"; // perfectly fine
    foo << endl; // everything is fine

    return 0;
}

Problem

I'm unsure as to whether this code will not compile. The example code I'm working with: ``` #include <iostream> using std::cout; using std::endl; class Foo { public: template<typename T> Foo& operator<<(const T& t) { cout << t; return *this; } }; int main() { Foo foo; foo << "Hello World"; // perfectly fine foo << endl; // shit hits the fan return 0; } ``` This is the error: ``` test.cpp:19:12: error: no match for ‘operator<<’ in ‘foo << std::endl’ test.cpp:19:12: note: candidates are: test.cpp:10:14: note: template<class T> Foo& Foo::operator<<(const T&) test.cpp:10:14: note: template argument deduction/substitution failed: test.cpp:19:12: note: couldn't deduce template parameter ‘T’ ``` I'm confused as to why it cannot substitute the function type of `endl` (`ostream& (*)(ostream&)`) for `T`, where it clearly is fine with doing it when you specify `cout << endl;` I find it additionally puzzling that this fixes the problem [ edited ] ``` Foo& operator<<(ostream& (*f)(ostream&)) { cout << f; return *this; } ``` In case the question isn't clear, I'm asking why it could not deduce the template in the first place.

Original source

Related problems