There are two different problems here, since your definition of explicit and implicit does not match the standard definition (on which most existing answers are based, written before you added your own example, which contains your own definition of explicit and implicit).
Ok, so let's first look at your definition of explicit, which will be (I suppose you call it explicit because you explicitly write the type name?):
integer int1 = integer(0, 100);
compared to your definition of implicit, which would be:
integer int1(1, 100);
In this case, the first “explicit” call does not really have any advantage over the second “implicit” call. But there is still a difference. The first actually creates a temporary object using a constructor with two arguments, which is then used to create int1 using the copy constructor. Although in practice the compiler usually optimizes this extra copy, it still won’t work if your copy constructor is private, while the second only needs a constructor with two arguments (you could even consider this a drawback).
But now the actual standard definitions are explicit and implicit. An explicit constructor call is any constructor call, well, in general, a call. Practically speaking, whenever you use the syntax in brackets () to create an object, you explicitly call the constructor, otherwise it is an implicit call to the constructor (so to speak, which is executed 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
Thus, the only constructors that can be called implicitly are the default constructor and any constructors with one argument (including copy and move constructors). A particular problem in this regard are single argument constructors that are not copy / move constructors:
struct integer { integer(int); };
This allows the compiler to implicitly call the constructor for type conversion, so any int implicitly converted to integer :
void func(integer); func(42); // implicit call to int-constructor
To prohibit this behavior, you must mark the explicit constructor:
struct integer { explicit integer(int); };
Which only allows it to be called explicitly (e.g. func(integer(42)) ) (but I think you already knew that). The advantage of this is that it does not create invisible / unwanted conversions behind the scenes, which can lead to all kinds of difficult to find problems and ambiguities regarding overload resolution. Therefore, it is common practice to flag conversion constructors (constructors without copying / moving with one argument) explicit and, most likely, also the reason that explicit conversion operators finally appeared in C ++ 11.
Thus, to summarize, according to your definition and example, there is no advantage in using integer int1 = integer(1, 100); instead of integer int1(1, 100); although that does (usually doesn't matter) the difference.
But according to standard definitions, explicit constructor calls have many advantages over implicit ones, since the only way to actually create an object explicitly is to use, well, an explicit constructor call, while implicit constructor calls are performed only behind the scenes in certain situations, they only work for zero- and designers with one argument (as Ashepler already pointed out). And explicitly marking conversion constructors as explicit has the advantage of prohibiting unwanted implicit conversions behind the scenes.