Reputation: 1480
I have a class called Log, which overload the operator <<:
class Log
{
public:
static void init(std::ostream&);
Log(const std::string&);
~Log(); //Write to the log here
Log& operator<<(bool);
Log& operator<<(const std::string&);
private:
std::stringstream text;
static std::ostream *stream;
std::string tag;
};
Ok, here is the problem, when i write to the log like this:
int main()
{
std::ofstream file;
file.open("log.txt",std::ios::app);
Log::init(file);
Log("[INFO]") << "Test";
file.close();
}
The operator<< which receives a bool is called, that write true to the log..., if i delete the operator implementation which receives a bool then the other one is called correctly. I think this happens because the char* can be interpreted as bool... but how can i fix it??
Upvotes: 2
Views: 98
Reputation: 14138
Replace <<(bool) by <<(OnlyBool), with OnlyBool defined as:
struct OnlyBool
{
OnlyBool(bool b) : m_b(b){}
bool m_b;
};
The idea is to use a type that is implicitly created from bool, but only bool.
(Sorry for the terseness, I'm writing this on my phone)
Upvotes: 1
Reputation:
You may drop all operator << in your class and have a template:
template <typename T>
Log& operator << (Log& log, const T& value) {
// ...
return log;
}
Upvotes: 1
Reputation: 76235
There are two possible <<
operators, one taking a std::string
, and one taking a bool
. The first requires a user-defined conversion, constructing a std::string
object from a char
array. The second requires a standard conversion, converting a pointer to a bool
(null pointer becomes false, non-null pointer becomes true). The rule here is that a standard conversion is better than a user-defined conversion (13.3.3.2 [over.ics.rank] /2), so the compiler chooses the bool
version.
Upvotes: 3
Reputation: 308101
Create a third operator<<
overload that takes a char *
parameter.
I think your analysis of the problem is probably correct, although surprising.
Upvotes: 4