Is it correct to say that the default constructor for the Point class is below constexpr?
W. Stroustrup has the following example on page 265 of his book "TCPL" 4th edition:
struct Point{
int x, y, z;
constexpr Point up(int d) { return {x, y, z+d}; }
constexpr Poind move(int dx, int dy) { return {x+dx, y+dy}; }
};
Further on page 266 it shows:
constexpr Point p1 {10, 20, 30}; // the default constructor is constexpr
From 7.1.5 / 4 in N4140 I find the following relevant items:
- (4.4) either its function body must be
= default
, or the compound operator of its function body must satisfy the constraints for a constexpr function-body;- (4.5) every nonvariant non-static data member and sub-object of the base class must be initialized (12.6.2);
I have two observations regarding the above points:
- Is it correct to say that the one generated by the default constructor for
struct Point
has a function body= default
? - Even if the answer to my question is above
yes
, I dispute the fact that the default constructed constructor forstruct Point
is equalconstexpr
, simply because this constructor does not initialize membersx
,y
andz
that is contrary to the previous point (4.5). Will I fix it here?
Edit . I present a third question that I think summarizes my main problem with this problem.
I cannot give an example constexpr
of a default constructor whose body is = default
. Let's assume this is NOT possible. The obvious question is: what is the purpose of item (4.4) in item 1.7.5 / 4?
source to share
- Yes. From [class.ctor]:
If there is no user-declared constructor for a class,
X
an implicit parameterless constructor is implicitly declared as a default (8.4) .
A function that is implicitly declared as default means that it functions as if it were explicitly declared as = default
.
- You're right. The default constructor cannot be used like
constexpr
, then cleared through [dcl.init]:
If the program calls the default initialization for an object of type const, the type T, T must be a class type with a user-supplied default constructor.
Thus, the following is ill-formed as there is no user-provided default constructor:
constexpr Point p; // error
We also see this in [dcl.constexpr]:
A
constexpr
specifier used in an object declaration declares the object asconst
. Such an object must be of a literal type and must be initialized . If initialized by a constructor call, that call must be a constant expression (5.20). Otherwise, or if the qualifier isconstexpr
used in a reference declaration, every fullexpression that appears in its initializer must be a constant expression. [Note: every implicit conversion used to convert initializer expressions, and every constructor call used to initialize, is part of such a complete expression. -end note]
[Example:
struct pixel { int x, y; }; constexpr pixel ur = { 1294, 1024 }; // OK constexpr pixel origin; // error: initializer missing
-end example]
Since the default constructor for us is not initialized (even if it didn't fail the user requested requirement), we can provide an initializer to do it ourselves:
constexpr Point q{}; // ok, all of q members are 0
Ultimately it doesn't matter:
constexpr Point p1 {10, 20, 30}; // the default constructor is constexpr
does not use a default constructor at all, and actually performs aggregate initialization that satisfies the "must be initialized" clause.
source to share