C++ Quiz58 of 173
Difficulty:
⬅️ Prev: 130Quiz ID: 131Next: 132 ➡️

According to the C++23 standard, what is the output of this program?

#include <iostream>

class C {
public:
  explicit C(int) {
    std::cout << "i";
  }
  C(double) {
    std::cout << "d";
  }
};

int main() {
  C c1(7);
  C c2 = 7;
}
Hint

How well does explicit constructors and copy-initialization play along?

Reveal answer

id

Explanation

These are two examples of initialization. The first form, C c1(7), is called direct-initialization, the second, C c2 = 7, is called copy-initialization. In most cases they are equivalent, but in this example they are not, since the int constructor is explicit.

§[over.match.ctor]¶1:

When objects of class type are direct-initialized, copy-initialized from an expression of the same or a derived class type (§[dcl.init]), or default-initialized, overload resolution selects the constructor. For direct-initialization or default-initialization that is not in the context of copy-initialization, the candidate functions are all the constructors of the class of the object being initialized.

So for the first case (direct-initialization), both the constructors are considered, and the one taking an int is a better match.

The paragraph continues:

For copy-initialization (including default initialization in the context of copy-initialization), the candidate functions are all the converting constructors (§[class.conv.ctor]) of that class.

And what is a converting constructor? §[class.conv.ctor]¶1:

A constructor that is not explicit specifies a conversion from the types of its parameters (if any) to the type of its class. Such a constructor is called a converting constructor.

So for the second case (copy-initialization), the explicit constructor taking an int is not even considered. Instead, a standard conversion sequence is used to convert the integer literal to a double, and the constructor taking a double (the only candidate) is used.

⬅️ Prev: 130Quiz ID: 131Next: 132 ➡️