类定义中的静态数据成员初始化



我在这里有一个问题,所以,为什么(对于什么?)不可能初始化类内部的静态变量?我管理的

http://eel.is/c draft/class.static.data#3

如果非挥发性非内线const静态数据成员是不可或缺的 或枚举类型,... 仍应在命名空间范围中定义 如果在程序中使用ODR和命名空间范围定义 不包含初始化器。

所以,这样的示例

struct X {
    static int const n = 7; // should be defined outside the class, 
                            // but it's compiles successfully
};

我看到了这个主题https://stackoverflow.com/a/16374286/9780989,有这样的例子

struct s
{
    static std::size_t const len = 10;
    int arr[len];
};
std::size_t const s::len; 

带有 -

的单词

"如果LEN在类定义中未初始化,则编译器 在下一行中不容易知道其价值以定义长度 arr。"

但实际上没有 std :: size_t const s :: len - 这行也成功地编译了,因此在哪些情况下它不应工作?https://gcc.godbolt.org/z/omkzeo

,所以我们走得更远,为什么我们不能初始化班级内的静态成员,const预选赛允许这一点,为什么没有我们做不到呢?const是什么允许在类中进行初始化?

的初始化?

您可能会说,由于ODR,我们不能初始化班级内部的静态成员,并且说stroustrup:

通常在标题文件中声明一个类,并且标题文件为 通常包含在许多翻译单元中。但是,避免 复杂的接头规则,C 要求每个对象都有唯一的 定义。如果C 允许在上课 定义需要存储在内存中的实体。

但这不是真的,为什么除编译器解决了模板类的静态成员是在标题中初始化的(翻译单元之外)的事实?

// templates are completely pushed into headers
template<typename T>
struct X {
    static int val;
};  
// here the static member of the template class is initialized in the header  
template<typename T>
int X<T>::val = 0; 
int main() {
    X<int> x;
}

好吧,我会尝试具体化我的问题:

  1. 为什么可以在类定义中定义const静态数据成员(如果它无用,则不需要定义它在班上)?
  2. 为什么没有const的静态数据成员可能不会在班级定义中定义(请参阅我对模板的想法与静态成员和关于此的静态词的课程(他吗作弊吗?)?

是的,我看到在C 17中我们允许内联使用,但我对这种情况不太感兴趣。

为什么(对于什么?)不可能初始化类内的静态变量?

它是不是如果它们是const。

但实际上没有std :: size_t const s :: len-这行也成功地编译了,因此在什么情况下它不应工作?

它之所以起作用,是因为该变量没有使用ODR。请参阅[basic.def.odr]:

一个变量x,其名称以潜在评估的表达E出现E odr被E使用,除非

  • x是参考...
  • x是非参考类型的变量,在恒定表达式中可用,没有可变的子对象,而e是非胆汁含量非阶级非阶级表达的潜在结果集的元素。应用LVALUE到RVALUE转换([Cons.lval]),或...

此外,ODR违规是无需诊断。从技术上讲,这对于缺少定义是正确的。优化可能会删除ODR-use,以免它们显示为错误。

尝试以下内容以odr-使用变量:

const int *ptr = &X::n;
  1. 为什么可以在类定义中定义const静态数据成员?

否。非内部const静态数据成员未由类定义中的声明定义。如果变量已使用ODR,则需要有一个定义(类之外)。

  1. 为什么在类定义中不定义静态数据成员[...](请参阅我对使用静态成员的模板类别以及对此的stroustrup单词的想法(他欺骗我们吗?)?
  2. )?

stroustrup对"复杂的链接规则"是正确的。当无法定义标题中的静态变量时,可以避免这些。

您对模板的观点很有意义。无论如何,需要这些复杂的链接规则,以使模板的静态变量成为可能。并且能够定义即使是未模拟的静态变量也具有优势。这些可能是委员会选择允许在C 17中定义静态成员的原因。请参阅:inline静态成员定义。

最新更新