Ayrosa
Ayrosa

Reputation: 3513

Trying to understand [expr.const] in C++14

Where in the C++14 Standard, does it prohibit the declaration of object a below?

class A{ int i = 1; public: A():i{1}{} };

int main()
{
    constexpr A a{};
}

See live example

Note that I highlighted the word declaration, because I don't think bullet points (2.7.2) or (2.7.3), in §5.19[expr.const]p2 is an answer for the question.

Upvotes: 0

Views: 108

Answers (2)

user743382
user743382

Reputation:

[dcl.constexpr]p9:

A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant expression (5.19). [...]

The error you're getting now is because your type is not a literal type. Your type is not a literal type because it does have a custom constructor, but doesn't have any constexpr constructor. The wording in the error message is rather clear about the exact requirements.

If you add a constexpr constructor (but not the default constructor), the error message changes:

class A{ int i = 1; public: A():i{1}{} constexpr A(int){} };

int main()
{
    constexpr A a{};
}

Now the error message becomes

error: call to non-constexpr function ‘A::A()’
     constexpr A a{};

This is the second part I bolded: it's not the initialiser that has to be a constant expression. You're right, your initialiser isn't an expression at all. It's the constructor call that must be a constant expression, and although it isn't expressed explicitly in the source code, it is an expression nonetheless. This is covered in [expr.const] rather clearly:

  • an invocation of a function other than a constexpr constructor for a literal class, a constexpr function, or an implicit invocation of a trivial destructor (12.4) [...]

to which you already refer in your question.

Upvotes: 3

Ralph Tandetzky
Ralph Tandetzky

Reputation: 23630

Well, your default constructor is not constexpr. Therefore, you cannot create a default constructed constexpr object.

Upvotes: 1

Related Questions