Question

It seems that in c++ in purely boolean context, operator char*() has higher precedence than operator bool() const; and enabling c++11 mode and using explicit operator bool() const doesn't help. Is this a bug in g++ or a misfeature in the language standard? Or is there a good reason for this crazy behavior that I am not seeing?

A simple demonstration of the issue:

#include <stdio.h>

struct A
{
    char buf[512];
    int err;

    operator char* () { return buf; }
    operator const char* () const { return buf; }
    operator bool () const { return !err; }
    // explicit operator bool () const { return !err; } // same problem
};

int main()
{
    A a;
    a.err = -42;
    if (a) {
        printf("lolwut?\n");
        return 1;
    }
    return 0;
}
Was it helpful?

Solution

As explained by @oakad — the elegant solution is to use explicit operator char*() in c++11 mode. This will ensure operator char*() simply doesn't get used in boolean context.

As explained by @bolov — the observed behavior is part of the language standard. According to 13.3.1, for the purpose of resolving overloaded functions, methods are considered to have an implicit object parameter. For methods declared without a ref-qualifier, this parameter is a reference to the class with the corresponding cv-qualifier.

So we effectively have the following situation:

char* op(A& a) { return a.buf; }
bool op(const A& a) { return !a.err; }

Since a was non-const in main(), the non-const operator gets picked. It doesn't matter whether we had operator char*() or operator int() or operator double() — a non-const cast operator which could be used in boolean context would have higher precedence than operator bool() const.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top