0

I want to wrap C++ streams in a template class such that all << operations that are defined for the streams are already available for the wrapper class.

Can you change the following code such that it compiles without altering the overall intention too much?

#include <iostream> class Foo { private: std::ostream& os; public: explicit Foo( std::ostream& os ) : os( os ) {}; template<class T> Foo& operator<<( const T& t ) { os << t << '!'; return *this; } }; int main() { Foo( std::cout ) << "test" << '\n'; // works fine Foo( std::cout ) << "test" << std::endl; // compilation error return 0; } 

I assumed that std::endl has some type and hence is 'caught' by the templated method.

3
  • std::endl is a templated function so its type can't be deduced by itself. Streams have an overload for functions of that form to help in type deduction. Commented Sep 13, 2018 at 8:35
  • This thread should be helpful. The context is a bit different (variadic parameter packs), but the answers should clarify what the issue is and how to mitigate it. Commented Sep 13, 2018 at 8:44
  • I need an example that actually compiles. Commented Sep 13, 2018 at 9:15

2 Answers 2

0

As suggested by kmdreko, you need to add an overload for template functions

(std::endl is a template function, not a class or simple type)

Like this :

#include <iostream> class Foo { private: std::ostream& os; public: explicit Foo(std::ostream& os) : os(os) {}; // for classes template<class T> Foo& operator<<(const T& t) { os << t << '!'; return *this; } // for endl Foo& operator<<(std::ostream& (*pf) (std::ostream&)) { os << pf; return *this; } }; 
Sign up to request clarification or add additional context in comments.

Comments

0

You should probably guard it with SFINAE and perfect-forward the argument.

 template<class T> auto operator<<(T &&t) -> decltype(os << std::forward<T>(t) << '!', *this) { return os << std::forward<T>(t) << '!', *this; } 

Now this should accept every argument std::ostream can print and fail to compile with everything else.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.