I know the concept that we can call the Constructor both Explicitly
and Implicitly
, and i have tested both the scenarios(generally till now my all purp
There are two different problems here, as your definition of explicit and implicit does not match the standard definition (on which most of the existing answers are based, being written before you added your example containing your own definition of explicit and implicit).
Ok so let's first consider your definition of explicit, which would be (I guess you call it explicit because you explicitly write the type name?):
integer int1 = integer(0, 100);
versus your definition of implicit which would be:
integer int1(1, 100);
In this case the first "explicit" call really doesn't have any advantage over the second "implicit" call. But there is still a difference. The first one actually creates a temporary using the two-argument constructor, which is then used to create int1
using the copy constructor. Although in practice the compiler will usually optimize away this additional copy, it still won't work if your copy constructor is private, whereas the second one only needs the two-argument constructor (you could even see this as disadvantage).
But now to the actual standard definitions of explicit and implicit. An explicit constructor call is any constructor call you, well, explicitly call. Practically speaking, whenever you use the parenthesis syntax ()
to create an object you explicitly call a constructor, otherwise it's an implicit constructor call (so to say, being done behind the scenes by the compiler):
integer int1; // implicit default constructor
integer int1(1, 100); // explicit two-arg constructor
integer int1 = integer(0, 100); // explicit two-arg constructor, implicit copy constructor
void func(integer); // function taking by-value
func(int1); // implicit copy constructor
So the only constructors that can be called implicitly are the default construtor and any one-argument constructors (including copy and move constructors). A special problem in this regard are one-argument constructors not being copy/move constructors:
struct integer
{
integer(int);
};
This allows the compiler to imlicitly call the the constructor to convert types, thus any int
is implicitly convertible to integer
:
void func(integer);
func(42); // implicit call to int-constructor
To disallow such behaviour you would have to mark the constructor explicit
:
struct integer
{
explicit integer(int);
};
Which only allows it to be called explicitly (e.g. func(integer(42))
) (but I guess you already knew this). This has the advantage that it doesn't introduce unnoticed/unwanted conversions behind the scenes, which can lead to all kinds of hard to find problems and ambiguities regarding overload resolution. It is therefore usual practice to mark any conversion constructors (one-argument non-copy/move constructors) explicit
, and most probably also the reason why C++11 finally introduced explicit
conversion operators.
So to sum up, according to your definition and example, there is really no advantage in using integer int1 = integer(1, 100);
instead of integer int1(1, 100);
, though it makes a (usually irrelevant) difference.
But according to the standard definitions, explicit constructor calls have plenty advantages over implicit ones, since the only way to actually construct an object explicitly is to use a, well, explicit constructor call, whereas implicit constructor calls are only done behind the scenes in certain situations and only work for zero- and one-argument constructors (as aschepler already pointed out). And explicitly marking conversion constructors as explicit
has the advantage of disallowing unwanted implicit conversions behind the scenes.