c++17:仅 header:class 静态变量错误

c++17: header only: class static variable errors

自 C++17 以来,我一直在试验更简单的方法来获取 class 静态变量。我正在编写一个 header-only 库。显然,inline 变量的新含义适用于此。

class thingy {
    static inline reporter rep;
};

但我一直遇到运行时错误。

我正在使用 Visual Studio 15.6.4

测试如下:

foo.h

#pragma once

#include <iostream>

using namespace std;

struct reporter {
    reporter() {
        cout << "reporter() - " << this << endl;
    }
    ~reporter() {
        cout << "~reporter() - " << this << endl;
    }
};

class thingy {
    static inline reporter rep;
};

main.cpp

#include "foo.h"
int main() {}

foo.cpp

#include "foo.h"

最令人失望的是,它打印出:

reporter() - 00007FF670E47C80
reporter() - 00007FF670E47C80
~reporter() - 00007FF670E47C80
~reporter() - 00007FF670E47C80

如您所见,它在同一位置构造了两次并销毁了两次 - 不好。

我是不是误解了 inline 变量的用途?

是否有另一种方法可以仅在 header 中获得 class 静力学?这在 C++17 中有变化吗?

这看起来像是 VS2017 中的一个错误。

可以找到一些相关的错误报告,尽管它们并不完全符合您的情况:

This will be addressed in 15.7 - thanks for the report! Combining multiple guards for adjacent static variables into a single guard is a backend optimization which can go wrong when inlining under certain circumstances. That's basically the issue here.

希望这个 静态变量 inline-ed 错误将在他们的下一个补丁中尽快修复。

与此同时,我发现在 Release Mode 中编译会使您的 reporter 按预期仅 初始化一次 ,而在 Debug Mode 中会出现此错误他们的后端优化

所以我想这至少不会进入您的产品。

这是 MSVC 中的错误。

静态 class 成员 thingy::rep,如 thingy,有 external linkageinline 说明符不会改变它。

因此整个程序中只能有one个实例,因此只能初始化一次

[class.static.data]/5:

Static data members of a class in namespace scope have the linkage of that class.