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.
class A
is 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.
A literal class type is a class type that has a trivial destructor, is either an aggregate type or has at least one non-move, non-copy constexpr constructor, and all of its base classes and non-static data members are non-volatile literal types.
The string literal type allows you to specify a set of possible string values for a variable, only those string values can be assigned to a variable. TypeScript throws a compile-time error if one tries to assign a value to the variable that isn't defined by the string literal type.
Generally, both terms, constants, and literals are used interchangeably. For example, “const int = 5;“, is a constant expression and the value 5 is referred to as a constant integer literal. There are 4 types of literal in C and five types of literal in C++.
Does anyone know why class
A
is a literal type?
It's not in C++11, but it is in C++14, for the reasons you cite in your post. However...
However, both Clang and GCC compile it successfully. So I am probably wrong.
You are not wrong. Neither are clang and gcc. The code is, indeed, well-formed despite A
not being a literal type... simply because nothing requires it to be a literal type. function
may be a constexpr
function, but it isn't being invoked as a constant expression. var
isn't a constexpr
object, so there's no enforced requirement that all the objects be of literal type. Had you tried:
constexpr int var = function(...);
then the code would be ill-formed, as in this case, function(...)
would need to be a core constant expression, which requires literal types, which is a requirement that in C++11 A
failed. (Actually, you'd also have the problem in C++14 that none of the A
s are constexpr
objects).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With