Constructor
Constructor

Reputation: 7473

Is the compiler generated constructor constexpr by default?

The following code compiles successfully with both clang++ 3.8.0 and g++ 7.2.0 (compilation flags are -std=c++14 -Wall -Wextra -Werror -pedantic-errors):

struct Foo
{
    constexpr operator bool() const
    {
        return false;
    }
};


int main()
{
    constexpr bool b = Foo{};

    (void)b;
}

Is such behavior of the compilers standard compliant? Note that adding any member (like int i;) to the Foo class doesn't change anything.

Upvotes: 5

Views: 1212

Answers (2)

eerorika
eerorika

Reputation: 238351

Yes, the implicit constructor is constexpr this case. In general, it depends on the sub-objects.

[class.ctor]

A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used (6.2) to create an object of its class type (4.5) or when it is explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (15.6.2) and an empty compound- statement. If that user-written default constructor would be ill-formed, the program is ill-formed. If that user-written default constructor would satisfy the requirements of a constexpr constructor (10.1.5), the implicitly-defined default constructor is constexpr. ... [snip]

Relevant requirements of a constexpr constructor:

[dcl.constexpr]

  • the class shall not have any virtual base classes;
  • for a non-delegating constructor, every constructor selected to initialize non-static data members and base class subobjects shall be a constexpr constructor;

Upvotes: 4

Bathsheba
Bathsheba

Reputation: 234715

Yes it is. The default constructor that a compiler generates, and the trivial constructor

Foo() = default;

both enable you to write constexpr bool b = Foo{};, assuming all class members can be constructed constexpr. Note that if you had written

Foo(){}

then constexpr would not be allowed. (An important difference between default and a constructor provided with an empty body.)

Upvotes: 1

Related Questions