Compiler error while initializing constexpr static class member

I declared the class as follows

class A { struct B { constexpr B(uint8_t _a, uint8_t _b) : a(_a), b(_b) {} bool operator==(const B& rhs) const { if((a == rhs.a)&& (b == rhs.b)) { return true; } return false; } uint8_t a; uint8_t b; }; constexpr static B b {B(0x00, 0x00)}; }; 

But g ++ says

error: field initializer is not constant

I can’t understand where I’m wrong.

+7
source share
2 answers

Clang is more useful:

 27 : error: constexpr variable 'b' must be initialized by a constant expression constexpr static B b {B(0x00, 0x00)}; ^~~~~~~~~~~~~~~~ 27 : note: undefined constructor 'B' cannot be used in a constant expression constexpr static B b {B(0x00, 0x00)}; ^ 8 : note: declared here B(uint8_t _a, uint8_t _b) : ^ 

Inside a member-variable-symbol-member-member element, constructors (including constructors of nested classes) are considered undefined; this is because the constructor refers to the values ​​of member variables, so member variables must be defined first, even if they are lexically later in the file:

 struct A { struct B { int i; constexpr B(): i{j} {} }; constexpr static int j = 99; }; 

A workaround is to place B outside A or possibly in the base class.

+9
source

This will work :

 #include <cstdint> #include <iostream> class A { struct B { bool operator==(const B& rhs) const { if((a == rhs.a)&& (b == rhs.b)) { return true; } return false; } uint8_t a; uint8_t b; }; public: constexpr static B b {0x61, 0x62}; }; int main() { std::cout << '{' << A::ba << ',' << A::bb << '}' << std::endl; } 

Removing the constructor from the struct will allow you to use a brace initializer. This will not help you if you plan to do something in the style of a constructor.

+2
source

Source: https://habr.com/ru/post/971646/


All Articles