Search code examples
c++castingcompiler-errorsboolean-expression

Why is a const pointer accidentally converted to bool?


I have a class with two constructors. One for bool and one for A*.

struct B
{
    explicit B(bool b)
    {
      std::cout << "B(bool)" << std::endl;
    }
    explicit B(A*)
    {
      std::cout << "B(A*)" << std::endl;
    }
};

When B should be constructed with const A* instead of A* -- const A* is converted to bool.

const A a;
B b(&a);

output: B(bool)


The desired solution would be a

compiler error : "no valid constructor for B(const A*)"

I already tried with explicit keyword, but it did not work.

running example at coliru


Solution

  • We can't stop the implicit conversion (bool conversion) from pointer to bool; You can add another overloaded constructor taking const A*, which will be selected in overload resolution when passing const A*, because it's an exact match and B::B(bool) requires an implicit conversion. With marking it as delete, the program becomes ill-formed if it's selected.

    struct B
    {
        explicit B(bool b)
        {
          std::cout << "B(bool)" << std::endl;
        }
        explicit B(A*)
        {
          std::cout << "B(A*)" << std::endl;
        }
        B(const A*) = delete;
    };
    

    LIVE

    Or you can mark the overloaded constructor taking pointer types delete, then all the pointer type can't be passed to B::B, except A* for which the constructor is declared seperately like you've done.

    template <typename T>
    B(T*) = delete;
    

    LIVE