DGomez
DGomez

Reputation: 1480

operator << strange behaviour

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

Answers (4)

&#201;ric Malenfant
&#201;ric Malenfant

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

user2249683
user2249683

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

Pete Becker
Pete Becker

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

Mark Ransom
Mark Ransom

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

Related Questions