kadina
kadina

Reputation: 5376

Use of explicit constructor if the constructor doesn't take any input parameters?

I understood 'explicit' concept related to constructors in C++ which will take single parameter as input. But I read on some websites that we need to change the constructor to explicit, irrespective of the number of parameters the constructor will take as input.

Can any one please help me to understand below issues.

  1. Why do we need to make a constructor as explicit if it doesn't take any input?
  2. What is the use of making a constructor as explicit if it takes more than one parameter and all the parameters are not default?

Upvotes: 1

Views: 914

Answers (2)

Andriy Tylychko
Andriy Tylychko

Reputation: 16256

Just to complement @R Sahu's answer from a different perspective:

The recommendation to use explicit for every constructor irrespective of how many arguments it takes can steam from the fact that strictly speaking every C++ constructor should be explicit by default and instead we would use implicit keyword: why constructors aren't explicit by default?

I saw this problem so many times: initially a class has a default constructor. Then after a while it's modified and a parameter is added. It's very easy to forget to add explicit in this case.

It's even easier to forget to add explicit when you remove a parameter from a two-arguments constructor. Also often your initial explicit one-parameter constructor got additional parameters or lost its parameter but explicit was left by mistake and compiler doesn't complain about this.

After a while your code starts to look like a christmas tree with many constructors that should be explicit but are not and others that are but shouldn't.

I suppose it's the reason why the website you mentioned recommends to use explicit always.

Upvotes: 2

R Sahu
R Sahu

Reputation: 206577

Why do we need to make a constructor as explicit if it doesn't take any input?

That seems incorrect to me. A constructor needs to be explicit if you don't want the constructor to be called automatically.

Say you have:

struct Foo 
{
   Foo() {}
   Foo(int) {}
};

void bar(Foo)
{
}

Then,

bar(1);

will work. It is translated as:

bar(Foo(1));

If there is a default constructor, i.e. one that does not take any arguments, there is nothing to convert from. You may not use:

bar();

and hope to get it translated as:

bar(Foo{});

What is the use of making a constructor as explicit if it takes more than one parameter and all the parameters are not default?

This one has some validity.

If you had:

struct Foo 
{
   Foo() {}
   Foo(int, int) {}
};

void bar(Foo)
{
}

You may not use

bar(10, 20);

or

bar((10, 20));

and hope to have it translated as:

bar(Foo(10, 20));

However, you may use:

bar({10, 20});

and it will be translated as:

bar(Foo{10, 20});

If you want to prevent use of this syntax, bar({10, 20}), you may make the constructor explicit. IMO, this has less utility. The potential for inadvertently misusing a constructor with one argument is real. The potential for inadvertently misusing a constructor with more than one argument is very small.

Upvotes: 2

Related Questions