More Effective C++ 5: Be wary of user-defined conversion funcitons
Two types of implicit conversions:
1. Single-argument constructors
2. Type conversion operators
e.g.
class Name{
public:
Name(const char * n):name(n){};
operator char * (){return name.c_str();}
....
private:
string name;
};
Name n1="Alex"; // uses single-argument ctor
const char * a=n1; // uses Name::operator char *()
cout<<n1; // uses Name::operator char *()
However, sometimes this kind of implicit type conversion is not what we want. If we actually want cout<<Name to ouput something like "My name is Alex", but we forgot to define the operator <<, we do want the compiler to remind us. However, when we call cout<<Name, we get the output "Alex".
To avoid this, don't define type conversion operators. Do it like this:
class Name{
public:
Name(const char * n):name(n){};
char * to_char(){return name.c_str();}
....
private:
string name;
};
...
cout<<n1; // error! no operator << defined which takes ...
cout<< n1.tochar(); // good, this works
To avoid single-argument constructors being called as implicit type conversions, you can simply specify a keyword called "explicit".
class Name{
public:
explicit Name(const char * n):name(n){};
....
private:
string name;
};
Name n1("Alex"); // fine, calls Name(const char *) explicitly
Name n1="Alex"; // error! can not convert from char * to Name