Reputation: 7473
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
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
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