int x = 1; // Not Constant
class A {
public:
int value = x;
int value2 { x };
A( int a ) : value( x ), value2( x ) {}
A( int a, int b ) : value{ x }, value2{ x } {}
constexpr A() : value{ 0 }, value2{ 0 } {}
};
constexpr int function( A obj1, A obj2, A obj3, A obj4, A obj5, A obj6, A obj7 ){
return 1;
}
int main(){
int y = 2; // Not Constant
A obj1 ( y );
A obj2 { y };
A obj3 = y ;
A obj4 = { y };
A obj5 ( y, y );
A obj6 { y, y );
A obj7 = { y, y };
int var = function( obj1, obj2, obj3, obj4, obj5, obj6, obj7 );
return 0;
}
C++11 Standard (ISO/IEC 14882:2011), Section 3.9, Paragraph 10 states (emphasis mine):
A type is a literal type if it is:
- a scalar type; or
- a reference type; or
- a class type (Clause 9) that has all of the following properties:
- it has a trivial destructor,
- every constructor call and full-expression in the brace-or-equal-initializers for non-static data members (if any) is a constant expression (5.19),
- 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
- it has all non-static data members and base classes of literal types; or
- an array of literal type.
In my opinion, taking into account the bullet in bold, class A is not a literal type in C++11 because there are constructor calls and a brace-or-equal-initializers for non-static data members that are not constant expressions. I tried putting constexpr before the constructor definition and also assigning the constructor call to a constexpr variable to check that indeed the compiler complains because those are not constant expressions. However, both Clang and GCC compile it successfully. So I am probably wrong.
- Does anyone know why
class Ais a literal type?
The bullet in bold was removed in C++14 (N3652), so I understand class A is a literal type in C++14. I need to know because function is constexpr, therefore each of its parameter types shall be a literal type (C++11/C++14 Standard, Section 7.1.15, Paragraph 3).
EDIT: In the Original Post I used a simple example to make it easier to read, and explained I already tried many combinations. Now I updated the example with some of those combinations to show I tried different constructor calls, definitions and non-static data member initializations. Thanks.
int x {y}or thisint x = y. I usually say member-initializer-list for the initializations in the constructor like when initializingvalueinA( int z ) : value( x ) {}, but I have also read a lot of people referring this like brace-or-equal initializer. Please correct me if I made any mistake. In any case, I tried many combinations of braces, equals, etc. initializations both for the object itself and for the variablevaluein the constructor, and the result is the same. Thanks.constexprfunction thateach of its parameter types shall be a literal type. That is where it is required inconstexpr int function( A obj ){ return 1; }. The problem is that both you and me thinkclass Ais not a literal type, but both Clang and GCC compile it like it is. So maybe we are missing something. Thanks.