Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constant expression initializer for static class member of type double

In C++11 and C++14, why do I need constexpr in the following snippet:

class Foo {
    static constexpr double X = 0.75;
};

whereas this one produces a compiler error:

class Foo {
    static const double X = 0.75;
};

and (more surprisingly) this compiles without errors?

class Foo {
    static const double X;
};

const double Foo::X = 0.75;
like image 494
Stefano Sanfilippo Avatar asked Jun 09 '15 20:06

Stefano Sanfilippo


People also ask

Can a static member function be const?

A static member function cannot be declared with the keywords virtual , const , volatile , or const volatile . A static member function can access only the names of static members, enumerators, and nested types of the class in which it is declared.

How to initialize constant in c++?

A constant variable must be initialized at its declaration. To declare a constant variable in C++, the keyword const is written before the variable's data type. Constant variables can be declared for any data types, such as int , double , char , or string .

How to define static member in c++?

We can define class members static using static keyword. When we declare a member of a class as static it means no matter how many objects of the class are created, there is only one copy of the static member. A static member is shared by all objects of the class.


1 Answers

In C++03 we were only allowed to provide an in class initializer for static member variables of const integral of enumeration types, in C++11 we could initialize a static member of literal type in class using constexpr. This restriction was kept in C++11 for const variables mainly for compatibility will C++03 we can see this from closed issue 1826: const floating-point in constant expressions which says:

A const integer initialized with a constant can be used in constant expressions, but a const floating point variable initialized with a constant cannot. This was intentional, to be compatible with C++03 while encouraging the consistent use of constexpr. Some people have found this distinction to be surprising, however.

CWG ended up closing this request as not a defect(NAD), basically saying:

that programmers desiring floating point values to participate in constant expressions should use constexpr instead of const.

For reference N1804 the closest draft standard to C++03 publicly available in section 9.4.2 [class.static.data] says:

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.

and the draft C++11 standard section 9.4.2 [class.static.data] says:

If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment expression is a constant expression (5.19). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [...]

this is pretty much the same in the draft C++14 standard.

like image 124
Shafik Yaghmour Avatar answered Sep 21 '22 14:09

Shafik Yaghmour