Compiler error when initializing constexpr static class member

可紊 提交于 2019-12-19 06:39:21

问题


I've declared a class in the following way

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

Can't figure out where I'm wrong.


回答1:


Clang is more helpful:

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) :
^

Within a brace-or-equal-initializer of a member variable, constructors (including constructors of nested classes) are considered undefined; this is because it is legitimate for a constructor to refer to the values of member variables, so the 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;
};

The workaround is to place B outside A, or perhaps within a base class.




回答2:


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::b.a << ',' << A::b.b << '}' << std::endl;
}

Removing the constructor from the struct will allow the braces initializer to work. This won't really help you if you were planning on doing something funky in the constructor.



来源:https://stackoverflow.com/questions/24527395/compiler-error-when-initializing-constexpr-static-class-member

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!