Reputation:
I'm trying to implement a manipulator for my stream
class. I don't know much about manipulators, but I think I'm doing everything right. The relevant parts of the code are below:
class stream
{
public:
stream& operator<<(bool b) { // send bool value and return *this; }
stream& operator<<(const char str[]) { // send string and return *this }
};
inline stream& endl(stream& s)
{
return s << "\r\n";
}
class stream stream;
int main()
{
stream << endl;
}
I don't know what I'm doing wrong, but instead of calling endl
the compiler is calling stream::operator<<(bool)
. Any idea?
Upvotes: 1
Views: 888
Reputation: 40070
Since your endl
is neither a bool
nor a const char[]
(it is a free function), it is implicitly converted to a bool
(true
) and the following function is called:
stream::stream& operator<<(bool b)
You could define endl
to be of a special type endl_t
and define the right operator for it:
#include <iostream>
#include <string>
#include <array>
//Just make the operators `explicit`. See [this excellent answer on SO](http://stackoverflow.com/a/8239402/5470596).
class stream
{
public:
stream& operator<<(bool b) { std::cout << "bool\n" ; return *this; }
stream& operator<<(const char str[]) { std::cout << "const char[]\n" ; return *this; }
};
struct endl_t {} endl;
stream& operator<<(stream& s, endl_t)
{
s << "\r\n";
return s;
}
int main()
{
stream s;
s << endl; // prints "const char[]"
}
Upvotes: 2
Reputation: 9991
Seeing stream << endl;
the compiler has to pick an overload from the operator <<
s you provided. endl
is not convertible to const char *
, but it is convertible to bool
, so that's what you get.
You probably meant to add an overload
stream& operator<<(stream &(*function)(stream &)) {
return function(*this);
}
inside of class stream
that handles function pointers correctly.
Upvotes: 5