1

Similar questions have been asked before, such as String literal matches bool overload instead of std::string.

But what I want to know is what should C++ developers do to prevent this from happening? As someone who writes C++ libraries for others to consume, what should I do to ensure this doesn't happen? Here is the example I ran into today, where a library had 2 initialize() methods:

void initialize(bool someflag) { /* ... */ }
void initialize(const std::string & name) { /* ... */ }

Now the problematic code was in the application that wanted to utilize this functionality and which called it in a manner similar to this:

initialize("robert");

At first glance you'd think that this would call initialize(string) but it actually calls the first initialize(bool) with a boolean flag set to true!

Yes, I know it can be fixed with this:

initialize( std::string("robert") );

But this puts the onus on the caller.


Edit for @zdan: I didn't consider the "solutions" in the other linked question to be great solutions since 1) I was hoping not to have to add a const char * version of every method that takes a bool or string, and 2) the template solution increases the maintainability of the code significantly for affected methods, renders them almost unreadable.

Stéphane
  • 19,459
  • 24
  • 95
  • 136
  • 1
    If you want to *prevent* it, you can `delete` the specific overload. For example `void initialize(const char*) = delete;`. You'll get a compiler error if you pass a string literal. – François Andrieux Jul 18 '19 at 19:53
  • 4
    Possible duplicate of [String literal matches bool overload instead of std::string](https://stackoverflow.com/questions/14770252/string-literal-matches-bool-overload-instead-of-stdstring) – zdan Jul 18 '19 at 19:55
  • A hacky way to fix it would be to add `template >>` to your `bool` overload – Parsa Jul 18 '19 at 19:59
  • Changing the signature to `void initialize(bool& someflag)` makes it less sticky with pointers, but then it won't bind to a `true` or `false` literal value. – Eljay Jul 18 '19 at 20:00
  • @zdan You serious? Did you even read the question? – Stéphane Jul 18 '19 at 20:04
  • Yup. The answer is in the question you reference (it's not the accepted answer) – zdan Jul 18 '19 at 20:08
  • 1
    The onus will either be on the caller (`initialize("robert"s)` if your compiler is new enough), or on the developer (you). Adding in the `const char *` overloads is less error prone and less work (longterm). There isn't a non-invasive solution that will automagically fix the problem. – 1201ProgramAlarm Jul 18 '19 at 20:21

1 Answers1

5

what should I do to ensure this doesn't happen?

One possibility is to create an overload that accepts a char const* and make it a pass through to the overload that accepts a std::string.

void initialize(char const* name) { initialize(std::string(name)); }
R Sahu
  • 204,454
  • 14
  • 159
  • 270