Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constexpr conditions for constructor

On this site, it is specified that:

"A constexpr function must satisfy the following requirements:

[...]

there exists at least one set of argument values such that an invocation of the function could be an evaluated subexpression of a core constant expression (for constructors, use in a constant initializer is sufficient) (since C++14). No diagnostic is required for a violation of this bullet."

What is the meaning of the bolded statement?

like image 775
user42768 Avatar asked Jul 23 '17 19:07

user42768


People also ask

Can a constructor be constexpr?

A constexpr function must accept and return only literal types. A constexpr function can be recursive. It can't be virtual. A constructor can't be defined as constexpr when the enclosing class has any virtual base classes.

What does constexpr constructor mean?

A constructor that is declared with a constexpr specifier is a constexpr constructor. Previously, only expressions of built-in types could be valid constant expressions. With constexpr constructors, objects of user-defined types can be included in valid constant expressions.

Do constexpr need to be static?

A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later. So, what does constexpr mean?

Is constexpr a default constructor?

defaulted default constructor cannot be constexpr because the corresponding implicitly declared default constructor would not be constexpr.


1 Answers

Looking at the linked defect report

struct X {
    std::unique_ptr<int> p;
    constexpr X() { }
};

Before C++14, this would be ill-formed due to [dcl.constexpr]

For a constexpr constructor, if no argument values exist such that after function invocation substitution, every constructor call and full-expression in the mem-initializers would be a constant expression (including conversions), the program is ill-formed; no diagnostic required.

Which mandates that there exists some argument (in this case, only the empty set) that can create a constant expression for the invocation of X::X, as in

constexpr X x;  // must be valid before C++14

Since std::unique_ptr isn't a literal type, it has a non-trivial destructor, this is impossible. Yet the defect report proposed that constexpr constructors should still be well-formed in such cases due to this kind of use case

X x;  // not constexpr, but initialization should be constant

Hence the rewording

For a constexpr function or constexpr constructor that is neither defaulted nor a template, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression, or, for a constructor, a constant initializer for some object , the program is ill-formed, no diagnostic required.

Translated, it means: a constexpr constructor is well-formed as long as it is a constexpr function, and its member initializations are also constexpr functions, even if the type itself can never be constexpr.

like image 92
Passer By Avatar answered Oct 25 '22 09:10

Passer By