令人难忘的工厂:不适用于默认的可构造对象

Unforgettable Factory: Doesn't work with default constructible objects

我指的是这个关于“令人难忘的工厂注册模式”的优秀博客 post:http://www.nirfriedman.com/2018/04/29/unforgettable-factory/

我注意到当自注册类型是默认可构造的时,这将停止工作。在代码提供的示例中,自注册类型(Animal base class)定义了一个带有int参数的构造函数。如果我稍微修改代码使 Animal 成为默认可构造的,工厂中的数据映射将保持为空,类型 CatDog 的对象将无法再通过工厂构造。

据我了解,问题在于 Animal class 不再调用 registerT 函数。但是,我不明白为什么会这样,以及需要进行哪些修改才能使其与默认可构造的 classes 一起使用。

有人可以解释一下吗?

有用:

int 论点是转移注意力。更改您修改的参数列表时

Dog(int x) : m_x(x) {}

成为

Dog() = default;

从用户提供的构造函数到默认构造函数。

实际上,这意味着编译器(我检查了 Clang 和 GCC)不会发出 Dog::Dog() 的函数定义,因此它不会 odr-use Animal::Registrar<Dog>::Registrar<Dog>(),这意味着它定义未实例化(成员函数体仅在使用 odr 时才实例化)。所以我们从不使用它的 registered 静态数据成员。

如果构造函数是默认的,那么我们实际上永远不会将工厂函数注册到映射中。事实上,在它再次成为用户提供之后,事情 start to work.

但是我无法理解为什么这会产生影响。用户提供的构造函数仍然是一个内联成员函数。内联函数定义也与 odr-usage 相关联。但也许这应该是另一个问题的主题。