explicit keyword in C++ tell the compiler that a certain constructor may not be used to implicitly cast an expression to its class type. It is an optional decoration for constructors that take exactly one argument. It only applies to single-argument constructors since those are the only constructors that can be used in type casting. The compiler will raise errors if explicit constructor is invoked using an assignment operator =.

Implicit Constructor

Following example shows implicit constructor invoking. Constructor of class Foo takes an integer as argument. In the main, first class instance assignment does not uses constructor. But compiler invokes Foo class constructor to create the class instance.

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

int main ()
{
  Foo a = 42;         //OK: calls Foo::Foo(int) passing 42 as an argument
  Foo b(42);          //OK: calls Foo::Foo(int) passing 42 as an argument
  Foo c = Foo(42);    //OK: calls Foo::Foo(int) passing 42 as an argument
  Foo d = (Foo)42;    //OK: calls Foo::Foo(int) passing 42 as an argument
}

In C++, a constructor with only one required parameter is considered an implicit conversion function. It converts the parameter type to the class type.

Explicit Constructor

To prevent this sort of implicit promotion or implicit type conversion, we use explicit keyword. Following example shows about declaring a constructor as explicit.

#include <iostream>
class Foo {
public:
  explicit Foo(int x);
};

Foo::Foo (int x){
    std::cout<<x;
}

int main()
{
  Foo a = 42;         //Compile-time error: can't convert 42 to an object of type Foo
  Foo b(42);          //OK: calls Foo::Foo(int) passing 42 as an argument
  Foo c = Foo(42);    //OK: calls Foo::Foo(int) passing 42 as an argument
  Foo d = (Foo)42;    //OK: calls Foo::Foo(int) passing 42 as an argument
}

The reason you might want to use explicit constructor is to avoid accidental construction that can hide bugs.

You can mix explicit constructors and non-explicit constructors in the same class. For example, this class has an explicit constructor taking a bool but a non-explicit constructor taking a double:

class Foo {
public:
  Foo(double x)        { std::cout << "Foo(double)\n"; }
  explicit Foo(bool x) { std::cout << "Foo(bool)\n"; }
};

int main()
{
  Foo a = true;       //OK: implicitly promotes true to (double)1.0, then calls Foo::Foo(double)
  Foo b = Foo(true);  //OK: explicitly calls Foo::Foo(bool)
}