33

Is there a difference between doing:

X() = default;

and

constexpr X() = default;

Default-constructing the class within constant expressions work fine, so is there a difference between these two examples? Should I use one over the other?

Me myself and I
  • 3,990
  • 1
  • 23
  • 47
  • Somebody may very well provide a constructive answer, I'm not going to copy and paste from a site where I found information from. Here is a few pointers in the *constexpr constructor* part http://en.cppreference.com/w/cpp/language/constexpr – woosah Dec 28 '13 at 02:34
  • @woosah It will still be a valid answer if you do copy/paste. –  Dec 28 '13 at 02:36
  • @remyabel Oh I didn't know that. Thought it would be a bit like yahoo answers then :S – woosah Dec 28 '13 at 02:37
  • @woosah: Yeah a bit :( Usually better to cite the standard, but a well-attributed secondary source can be acceptable on occasion. – Lightness Races in Orbit Dec 28 '13 at 02:38

1 Answers1

33

Since the implicit constructor is actually constexpr in your case…

[C++11: 12.1/6]: [..] If that user-written default constructor would satisfy the requirements of a constexpr constructor (7.1.5), the implicitly-defined default constructor is constexpr. [..]

[C++11: 7.1.5/3]: The definition of a constexpr function shall satisfy the following constraints:

  • it shall not be virtual (10.3);
  • its return type shall be a literal type;
  • each of its parameter types shall be a literal type;
  • its function-body shall be = delete, = default, or a compound-statement that contains only
    • null statements,
    • static_assert-declarations
    • typedef declarations and alias-declarations that do not define classes or enumerations,
    • using-declarations,
    • using-directives,
    • and exactly one return statement;
  • every constructor call and implicit conversion used in initializing the return value (6.6.3, 8.5) shall be one of those allowed in a constant expression (5.19).

… the declarations are actually equivalent:

[C++11: 8.4.2/2]: An explicitly-defaulted function may be declared constexpr only if it would have been implicitly declared as constexpr, and may have an explicit exception-specification only if it is compatible (15.4) with the exception-specification on the implicit declaration. If a function is explicitly defaulted on its first declaration,

  • it is implicitly considered to be constexpr if the implicit declaration would be,
  • it is implicitly considered to have the same exception-specification as if it had been implicitly declared (15.4), and
  • in the case of a copy constructor, move constructor, copy assignment operator, or move assignment operator, it shall have the same parameter type as if it had been implicitly declared.

So do either — it doesn't matter.

In the general case, if you definitely want a constructor to be constexpr, though, it may be wise to leave the keyword in so that you at least get a compiler error if it does not meet the criteria; leaving it out, you may get a non-constexpr constructor without realising it.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055