难忘的工厂:什么时候实例化构造函数?

Unforgettable Factory: When is constructor instantiated?

我正在实施 unforgettable factory。 一切正常,但有一件事:classes 有时没有注册。

我认为关键部分是 Registrar::registered 成员。如果使用它,"The really fun part" 调用注册 class.

registerT 函数

在我的玩具示例中,class 未注册,除非

  1. 构造函数已实现(在 cpp 文件中或内联)。显式默认构造函数和构造函数继承 (*​​) 不注册 class.
  2. 基class(Animal)中有一个虚方法,在注册的class中实现重写cpp 文件。内联实现不起作用(与内联 ctor 不同)。

是我弄错了还是作者遗漏了什么?在我的实际应用程序中,some classes 已注册,而 some 未注册,我无法发现差异(所有 classes满足(1.)),所以我必须加深理解。

我的问题是:registerT究竟在什么情况下被称为?也就是说:Registrar的构造函数什么时候实例化? 我应该把 (void) registered; 放在哪里,以便 总是 实例化?

(*) 为了使构造函数继承起作用,我制作了 FactoryFactory<...>::Registrar public

的构造函数

编辑: pointed me to the unforgettable factory blog post这不是重复的。该问题的作者显然只是忘记添加 "The really fun part" 和关键的几乎为空的构造函数。我没有忘记他们。 我想知道为什么这个关键的几乎为空的构造函数没有被实例化,尽管它在那里。

编辑:解决方案 是不使用建议的模式。它似乎不适合生产代码,请参阅 the relevant issue

[basic.start.dynamic]/3 A non-initialization odr-use is an odr-use (6.2) not caused directly or indirectly by the initialization of a non-local static or thread storage duration variable.

[basic.start.dynamic]/4 It is implementation-defined whether the dynamic initialization of a non-local non-inline variable with static storage duration is sequenced before the first statement of main or is deferred. If it is deferred, it strongly happens before any non-initialization odr-use of any non-inline function or non-inline variable defined in the same translation unit as the variable to be initialized.

这就是导致这个和类似的自助注册方案失败的原因。有一个翻译单元包含实体的定义,这些实体在程序的其他地方没有被引用,而只能由同一翻译单元中定义的静态变量的初始化程序引用。实现可能会选择推迟该静态变量的初始化,直到它的翻译单元中的任何东西都被 odr-used——这是永远不会的。