c++ - constexpr for null-initialized constructor in a derived class -


i have similar following

class base { public:     explicit base(int* i) noexcept { type = new int; *type = *i; };     constexpr base(std::nullptr_t) : type(nullptr) { };     ~base() { cout << "destroying!" << endl; delete type; }; protected:     int* type; };   class derived : public base { public:     explicit derived(int* i) noexcept : base(i) { };     //constexpr derived(std::nullptr_t) : type(nullptr) { };     //constexpr derived(std::nullptr_t) : base(nullptr) { };     ~derived() { }; }; 

i achieve constexpr null constructor derived class, compiler complains lot 2 options , similar tests have done.

of course code more complex, have opaque handler , destructor should behave in more complex way. resource free-ing same (no need multiple destructors, base one).

i don't know how achieve this, maybe going through wrong path? ideas? expect able like:

derived a(nullptr); derived b(handler1); base c (nullptr); base d (handler2); 

and, in cleanup, both handler1 , handler2 managed in way.

edit:

clang (version 3.4) complains:

error: constexpr constructor never produces constant expression [-winvalid-constexpr] 

and gcc (version 4.8 [edit: multiple versions, haven't checked all]) doesn't complain when using

constexpr derived(std::nullptr_t) : base(nullptr) { }; 

in fact, gcc seems wanted achieve, not understand constexpr enough know compiler doing right , how can amend problem.

the type of constant expression must literal type. in fact, entire purpose of "literal type" taxon "be thing can constant expression". see [expr.const]:

a conditional-expression e core constant expression unless evaluation of e, following rules of abstract machine (1.9), evaluate 1 of following expressions:

...

— invocation of function other a constexpr constructor literal class, constexpr function,

...

therefore, constexpr constructor allows produce constant expressions on literal classes, , otherwise, compiler telling you, "never produce constant expression".

a literal class constrained [basic.types] in way:

a type literal type if is:

...

— class type (clause 9) has of following properties:

  • it has trivial destructor,
  • it aggregate type (8.5.1) or has @ least 1 constexpr constructor or constructor template not copy or move constructor, and
  • all of non-static data members , base classes of non-volatile literal types.

however, of c++14 (particularly, of n3652), constexpr constructors have another, unrelated use: permit static initialization (in sense of [basic.start.init]):

a constant initializer object o expression constant expression, except may invoke constexpr constructors o , subobjects if objects of non-literal class types [note: such class may have non-trivial destructor — end note].

so recap: of c++14, constexpr has 2 uses:

  1. the c++11 interpretation: "constant expression" expression identical value (i.e. evaluation has no side effects); constexpr variables placeholders value , not intended used object identity, , expected constant expressions can freely replaced (compile-time knowable) value.

  2. the c++14 constexpr functions, including constructors: these functions, including constructors, may called in static initialization phase constant-initialize variables static storage duration. if variables objects, still retain object identity , may need dynamic destruction, initialization happens before dynamic initialization , not subject ordering.


Comments

Popular posts from this blog

matlab - "Contour not rendered for non-finite ZData" -

delphi - Indy UDP Read Contents of Adata -

javascript - Any ideas when Firefox is likely to implement lengthAdjust and textLength? -