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?