Saturday, February 7, 2009

Recovery from implicit habits by using explicit keyword

This might be something ordinary for many.
But its only very recently that I have changed my coding style.
I find myself using the keyword explicit almost always now. Thus I would like to share why I started.

class Foo
{
public:
Foo(int x) {}
};


Its an innocent Foo class with a constructor that accepts an integer.

Constructors with single parameters servers us dual purpose:
1. just like all constructors it assists in construction of an object.
2. it behaves as an implicit conversion operator, that converts from type int to type Foo.

Consider this:

Foo f1(0); // line 1 - works
Foo f2 = 0L; // line 2 - works
Foo f3 = NULL; // line 3 - works

Line 1 is straight forward.
Line 2 is quite intuitively doing an implicit conversion from long to int.
Line 3 is plain WRONG. Its supposed to be a pointer type, but let say a typo occured. Surprisingly enough, it does compile.

Line 2 & 3 works because compiler internally turns off its static type checking (due to implicit conversion).

We would definitely want to avoid unintended usages like the "line 3" example.

This is something that we can achieve by the "explicit" keyword.

The only place explicit keyword can be used is in constructors.

For eg:

class Foo
{
public:
explicit Foo(int x) {}
};


Now if we have explicit, these are the new results:

Foo f1(0); // line 1 - works
Foo f2 = 0L; // line 2 - doens't work
Foo f3 = NULL; // line 3 - doesn't work


and in order make those lines work we will have to be more explicit during construction.

Foo f1(0); // line 1 - works
Foo f2 = static_cast<Foo> (0L); // line 2 - works
Foo *f3 = NULL; // line 3 - works


Explicit keyword helps us not to do silly mistakes which can turn be quite lethal if not paid attention to.

IMHO, its wise to always use the explicit keyword in your constructors with single parameter.
It also makes sense to use explicit keyword with constructors that have more than x parameters but (x-1) parameters have default values.