constexpr for null-initialized constructor in a derived class

前端 未结 1 917
死守一世寂寞
死守一世寂寞 2021-01-07 02:24

I have something similar to the following

class Base {
public:
    explicit Base(int* i) noexcept { type = new int; *type = *i; };
    constexpr Base(std::nu         


        
相关标签:
1条回答
  • 2021-01-07 02:37

    The type of a constant expression must be a literal type. In fact, the entire purpose of the "literal type" taxon is to "be the thing that can be a constant expression". See [expr.const]:

    A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:

    ...

    — an invocation of a function other than a constexpr constructor for a literal class, a constexpr function,

    ...

    Therefore, a constexpr constructor only allows you to produce constant expressions on literal classes, and otherwise, as your compiler is telling you, it would "never produce a constant expression".

    A literal class is constrained by [basic.types] in this way:

    A type is a literal type if it is:

    ...

    — a class type (Clause 9) that has all of the following properties:

    • it has a trivial destructor,
    • it is an aggregate type (8.5.1) or has at least one constexpr constructor or constructor template that is not a copy or move constructor, and
    • all of its non-static data members and base classes are of non-volatile literal types.

    However, as of C++14 (particularly, as of N3652), constexpr constructors have another, unrelated use: They permit static initialization (in the sense of [basic.start.init]):

    A constant initializer for an object o is an expression that is a constant expression, except that it may also invoke constexpr constructors for o and its subobjects even if those objects are of non-literal class types [Note: such a class may have a non-trivial destructor — end note].

    So to recap: As of C++14, constexpr has two uses:

    1. The C++11 interpretation: a "constant expression" is an expression that is identical to its value (i.e. its evaluation has no side effects); constexpr variables are just placeholders for their value and not intended to be used for their object identity, and it is generally expected that constant expressions can be freely replaced with their (compile-time knowable) value.

    2. The C++14 constexpr functions, including constructors: These functions, including constructors, may be called in the static initialization phase to constant-initialize variables with static storage duration. If the variables are objects, they still retain their object identity and may need dynamic destruction, but their initialization happens before any dynamic initialization and is not subject to ordering.

    0 讨论(0)
提交回复
热议问题