1

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?
Mike Aguilar
  • 348
  • 2
  • 3
  • 14
kadina
  • 5,042
  • 4
  • 42
  • 83
  • 2
    Could you cite where did you read that? IMHO it seems wrong. If you want explicit constructor, than you gotta use single parameter. – Vilius Sutkus '89 Apr 30 '18 at 20:14
  • 2
    There does seem to be some functional differences with an explicit default constructor as well: https://stackoverflow.com/questions/48677746/explicit-default-constructor – clcto Apr 30 '18 at 20:16
  • @Vilius `explicit` makes perfect sense for a constructor with multiple arguments if some (or all) of those arguments have default values - in rhat case it is still a "conversion constructor". – Jesper Juhl Apr 30 '18 at 20:22
  • Yeah, makes sense. My initial comment is wrong. – Vilius Sutkus '89 Apr 30 '18 at 20:23

2 Answers2

2

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.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Can you please let me know any practical use of explicit constructor even in case of single parameter? – kadina Apr 30 '18 at 21:29
  • @kadina, hop on over to https://stackoverflow.com/questions/12437241/c-always-use-explicit-constructor and follow the link to http://www.sjbrown.co.uk/2004/05/01/always-use-explicit/. – R Sahu Apr 30 '18 at 21:37
  • @kadina implicit single arg ctor is called conversion ctor; meaning that input and resultant object are somewhat equivalent(eg. complex and real numbers). Consider a vector and its size: does it make sense to init the vector with an assignmentlike syntax? – Red.Wave May 01 '18 at 08:30
2

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.

Andriy Tylychko
  • 15,967
  • 6
  • 64
  • 112