为什么可以在类中初始化“const static int”成员,而不能初始化“const static other”成员?

Why can a "const static int" member be initialized within a class, but not a "const static other" member?

提问人:SleepingCat 提问时间:8/5/2023 最后编辑:Jan SchultkeSleepingCat 更新时间:8/6/2023 访问量:168

问:

看看下面的代码,这编译了。但是,代码会给出错误。它们的修饰符都是 ,那么为什么会起作用,但其他浮点类型会导致错误?const static int num1 = 8;const static double num2 = 8.8;const staticintdouble

struct S {
    const static int num1 = 8;       // OK
    const static double num2 = 8.8;  // error
};

我尝试了一些内置类型的 C++,发现

  • 整数成员,如 、 、 和 可以在类中定义并直接初始化,而intshortlongcharconst static
  • 浮点成员,例如 和 can不能。floatdouble

这让我很困惑。

C++ 静态成员

评论

0赞 Iron Fist 8/5/2023
为什么两者都使用相同的标识符?,您是否尝试过使用不同的标识符名称?
1赞 Eljay 8/5/2023
如果它与您的问题有关,那么添加到语言中的可用性是否支持这一点。 甚至更好。constexpr static double a = 8.8;constexpr static inline double a = 8.8;
1赞 tbxfreeware 8/5/2023
尝试另外,这个问题可能类似于 c++ 中的静态常量双精度。请参见constexpr 说明符constexpr static double a = 8.8;
2赞 user17732522 8/5/2023
对于限定的整型和枚举类型,这是一个特定的例外,仅出于历史原因而存在。如果您使用的是 C++17 或更高版本,则可以忽略它并使用 either 而不是 如果您希望该值是编译时常量或其他方式,您将能够以这种方式初始化任何静态成员。constconstexprconstinline

答:

2赞 LiuYuan 8/5/2023 #1

我不知道“为什么浮点类型不能在类中初始化,而其他内置类型可以”,但我可以提供其他方法来初始化类中的成员:const doubleconst static

  1. 代替写,你可以写,这两者的区别可以在这里找到const double a = 8;constexpr double a = 8;

  2. 您可以在类之外初始化它,如下所示:

    class myclass {
        public:
            const static double a;
    };
    
    const double myclass::a = 8;
    
5赞 Iron Fist 8/5/2023 #2

float数据类型是非整型类型,需要 constexpr 说明符而不是:const

struct S {
    constexpr static double af = 8.8;
    const static int ai = 8; 
};

原始错误消息可以帮助您调试此问题:

error: 'constexpr' needed for in-class initialization of static data member 
'const double myclass::af' of non-integral type
2赞 Brian Bi 8/6/2023 #3

好吧,事实上,成员可以在类中初始化 - 如果你声明它们。如果要将其初始化为的值也恰好是常量表达式,则可以声明它,在这种情况下,无需声明它,因为数据成员是自动内联的。static const doubleinlineconstexprinlinestatic constexpr

但是,当成员不是内联成员时,则意味着只有一个转换单元负责提供该成员的定义,而定义负责初始化。因为类定义需要被 d 到每个想要访问该类成员的翻译单元中,这意味着类中成员的声明不应该是一个定义(因为这会导致多个定义)。因此,您必须在类外部的某个位置提供静态成员的单个定义,并且该单个定义是负责初始化它的定义。static const double#include