Problematic C++03 code:
#include <cstddef>
struct Foo {
explicit Foo(const char *){}
Foo &operator=(const char *) {return *this;}
Foo &operator=(char) {return *this;}
};
int main() {
Foo s("foobar");
s = NULL;
}
Error:
In file included from /opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/cstddef:50,
from <source>:1: <source>: In function 'int main()': <source>:9:9: error: ambiguous overload for 'operator=' (operand types are 'Foo' and 'long int')
9 | s = NULL;
| ^~~~ <source>:4:10: note: candidate: 'Foo& Foo::operator=(const char*)'
4 | Foo &operator=(const char *) {return *this;}
| ^~~~~~~~ <source>:5:10: note: candidate: 'Foo& Foo::operator=(char)'
5 | Foo &operator=(char) {return *this;}
| ^~~~~~~~
If I understand correctly, the source of the problem comes from the fact that NULL
in C++03 can act as both an integer and a pointer. I am also aware that C++11 and later provide nullptr
to solve this problem. Upgrading to C++11 is not an option for me.
Question: how is this problem solved in practice and how can I keep the ability to provide overloads?
One way is to tell the user not to use NULL
. Is there a programmatic solution?
A way to achieve it is to use a proxy struct for char
, which will make operator=(const char*)
preferrable. Like this:
#include <cstddef>
struct MyChar
{
MyChar(char c) : c(c){}
operator char() {return c;}
char c;
};
struct Foo {
explicit Foo(const char *){}
Foo &operator=(const char *) {return *this;}
Foo &operator=(MyChar) {return *this;}
};
int main() {
Foo s("foobar");
s = NULL;
s = 'x';
s = "foo";
}