从C ++ 17开始,我一直在尝试更简单的方法来获取类静态变量。我正在编写一个仅限标题的库。显然inline
对变量的新含义适用于此。
class thingy {
static inline reporter rep;
};
但我一直在收到运行时错误。
我正在使用Visual Studio 15.6.4
要测试,请执行以下操作:
thingy
有一个静态成员变量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
变量的用途?
是否有另一种方法只能在标题中获取类静态?这在C ++ 17中发生了变化吗?
答案 0 :(得分:6)
它看起来像VS2017中的一个错误。
可以找到一些相关的错误报告,但它们并不完全符合您的情况:
这将在15.7中解决 - 感谢您的报告! 将相邻静态变量的多个保护组合成单个保护是后端优化,在某些情况下内联时可能会出错。这基本上就是问题所在。
希望在内联编辑错误时,这个静态变量很快就会在下一个补丁中修复。
与此同时,我发现在Release Mode
中进行编译会使reporter
初始化只按预期,而在Debug Mode
中,会出现后端优化。
所以我想这至少不会进入你的产品。
答案 1 :(得分:0)
这是MSVC中的一个错误。
静态类成员thingy::rep
与thingy
一样external linkage,inline
说明符不会改变它。
因此,整个程序中只能有one个实例,因此只能初始化一次。
命名空间范围内的类的静态数据成员具有该类的链接。