I have a class, X
, and it has the following constructors:
class X{
X(int64_t, int16_t, bool, int8_t);
X(int64_t, int16_t, bool);
X(double);
X(double, FT);
explicit X(const string&);
X(const string&, Y);
};
The problem is the compiler once created an X object passing just a bool (presume it was the double constructor which allowed this?) and it caused an issue.
To prevent this I made the bool constructor explicit and deleted it:
explicit X(bool) = delete;
but now I get compiler errors:
EXPECT_EQUALS(X("9.8901099"), a/b);
EXPECT_EQUALS(X{"56267"}, x);
X x{"-56267E-1"};
X b("5");
where the compiler says I have made use of deleted function explicit X(bool) = delete
How do I prevent an object of X being created from a bool?
This happens because bool
is a better match for const char[]
than std::string
. When you have no ctor accepting bool
then the std::string
one is chosen. When you have a ctor with bool
then this overload is selected. Only it is deleted so it is illegal to call it.
Lets see this behavior with a simple free overloaded function:
auto foo(int) { cout << "foo int" << endl; }
auto foo(std::string const &) { cout << "foo string" << endl; }
auto main() -> int {
foo(3); // int
foo("Asdf"); // std::string
}
When you add a bool
overload:
auto foo(int) { cout << "foo int" << endl; }
auto foo(std::string const &) { cout << "foo string" << endl; }
auto foo(bool) { cout << "foo bool" << endl; }
auto main() -> int {
foo(3); // int
foo("Asdf"); // bool (also warning implicit conversion turn string literal into bool)
}
The solution is to add a char const *
overload:
auto foo(int) { cout << "foo int" << endl; }
auto foo(std::string const &) { cout << "foo string" << endl; }
auto foo(char const *s) {
cout << "foo char const *" << endl;
// possibly:
return foo(std::string{s});
}
auto foo(bool) = delete;
auto main() -> int {
foo(3); // int
foo("Asdf"); // char const *
foo(true); // error
}
Because some legacy code uses and returns char *
instead of char const *
you might need to add a char *
overload too.