所以我正在尝试创建一个基于CRTP的工厂。为简单起见,我将仅包含此处相关的内容。我有两个可能彼此不相关的问题,但一直在寻找关键字。
#include <bits/stdc++.h>
using namespace std;
static auto& GetFactoryMap() {
static vector<string> GLOBAL_FACTORY_MAP;
return GLOBAL_FACTORY_MAP;
}
template <typename Derived>
struct Registrar {
static int DoRegister() {
auto name = typeid(Derived).name();
GetFactoryMap().emplace_back(name);
return 1;
};
inline static const int _hello = DoRegister();
};
struct Foo : public Registrar<Foo> {};
int main() {
cout << GetFactoryMap().size();
}
使用
x86-64 clang-8.0.0
编译,标记-std=c++17
。
问题 1: 程序返回
0
:https://godbolt.org/z/5c74TePT5。我期望它打印 1
,因为定义类 Foo
还应该定义 Registrar<Foo>
,这反过来将初始化 _hello
并调用 DoRegister()
。
但是当我这样做时:
int main() {
cout << Foo::_hello << endl;
cout << GetFactoryMap().size();
}
然后它打印了
1
(_hello
)和 1
(地图大小)。
问题2:所以我找到了如何通过在
_hello
构造函数中虚拟调用Registrar
来解决第一个问题。
template <typename Derived>
struct Registrar {
Registrar() {
(void)_hello;
}
...
}
但问题是,我仍然不知道为什么它可以解决问题。即使在我这样做之后,
DoRegister
似乎只有在类定义之外有一个空构造函数或默认构造函数时才会被调用,如全局地图大小所示只有2:https://godbolt.org /z/Me53q1x86.
这里发生了什么?