0

This is somewhat contrived code in order to come up with a minimal example. Here's my sample:

#include <iostream>
#include <memory>
#include <string>

using std::cout;
using std::endl;
using std::string;

class Foo {
public:
    Foo(const std::string &, bool) {
        std::cout << "Bool version." << endl;
    }
    Foo(const std::string &, const std::string &) {
        std::cout << "String version." << endl;
    }
};

using Ptr = std::shared_ptr<Foo>;

int main(int, char **) {
    cout << "Make them." << endl;
    Ptr p1 = std::make_shared<Foo>("Hello", false);
    Ptr p2 = std::make_shared<Foo>("Hello", "there");
    Ptr p3 = std::make_shared<Foo>("Hello", string{"there"});
    cout << "Done." << endl;
}

Build and run:

$ g++ --std=c++17 Foo.cpp -o Foo && Foo
Make them.
Bool version.   <-- Expected
Bool version.   <-- const char * turning into a bool instead of a string
String version. <-- Expected
Done.

(The reason I have overloaded operators is due to backwards compatibility.)

I'm rather annoyed that the compiler prefers the bool version when passing in a const char * instead of understanding that's a string. I think the only ways to fix this are one of:

  • Use different method names so there's no method overloading
  • Cast the third argument the way I did in my example

Is the compiler picking the first one that it can make work? Or does it prefer turning a const char * into a bool even when it could change it into a string?

How would you fix this?

Joseph Larson
  • 8,530
  • 1
  • 19
  • 36
  • Note: changing the order of the constructors doesn't change behavior. It still picks the boolean version. – Joseph Larson Jun 28 '21 at 00:27
  • This doesn't go into fixing it (making it a bad dupe), but good read: https://stackoverflow.com/questions/66452781/why-const-char-implicitly-converted-to-bool-rather-than-stdstring – chris Jun 28 '21 at 00:28
  • It doesn't have to fix it, just explain the reason for the observed behavior. – Sam Varshavchik Jun 28 '21 at 00:30
  • The fix is actually quite simple: If you have functions with `std::string` _or_ `bool` as an alternative you should add a third with `const char*` which might just be a wrapper for the first. – Scheff's Cat Jun 28 '21 at 05:45

0 Answers0