c++constructorlist-initializationexplicit-constructor

C++: Particularities of considering but not calling constructors


On cppreference about list-initialization in the second intend (for copy-list-initialization) it says:

copy-list-initialization (both explicit and non-explicit constructors are considered, but only non-explicit constructors may be called)

What exactly is the difference about constructors being 'considered' and being actually 'called'. Why consider constructors, that may not be called anyway?


Solution

  • The difference between "considered" and "called" is that "considered" means the candidate function participates in overload resolution while "called" means that it is actually chosen as the best match. Explicitly (pun not intended), this means that if an explicit constructor is selected during copy list initialization, it's forbidden. For example consider this scenario:

    struct String {
      explicit String(int size);
      String(char const *value);
    };
    
    String s = { 0 };
    

    Here, you are using an implicit conversion where the explicit constructor would be a better match so the compiler rightfully rejects it. You need to write String{ 0 } to fix the code. Now imagine if explicit constructors were not considered and the former was legal code. It would be very strange to have an explicit constructor that did nothing.