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 for struct Point

    is equal constexpr

    , simply because this constructor does not initialize members x

    , y

    and z

    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?

+3


source to share


1 answer


  • 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

.

  1. 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 as const

. 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 is constexpr

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.

+5


source







All Articles