Reputation: 5376
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.
Upvotes: 1
Views: 914
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
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