为什么 make_unique 调用会编译? make_unqiue 不要求它的模板参数是一个完整的类型吗?
struct F;
int main()
{
std::make_unique<F>();
}
struct F {};
问题源于我的PIMPL实现的“问题”:
我确实理解为什么必须在实现类 (PIMPL) 的 cpp 文件中由用户声明和定义析构函数。
但是移动包含 pimpl- 的类的构造函数仍然可以编译。
class Object
{};
class CachedObjectFactory
{
public:
CachedObjectFactory();
~CachedObjectFactory();
std::shared_ptr<Object> create(int id) const;
private:
struct CacheImpl;
std::unique_ptr<CacheImpl> pImpl;
};
现在是cpp文件:
// constructor with make_unique on incomplete type ?
CachedObjectFactory::CachedObjectFactory()
: pImpl(std::make_unique<CacheImpl>())
{}
struct CachedObjectFactory::CacheImpl
{
std::map<int, std::shared_ptr<Object>> idToObjects;
};
//deferred destructor
CachedObjectFactory::~CachedObjectFactory() = default;
有人能解释一下为什么会编译吗? 为什么 build 和破坏之间有区别? 如果析构函数的实例化和default_deleter的实例化有问题,为什么make_unique的实例化没有问题?
最佳答案
make_unique
有多个实例化点:翻译单元的末端也是一个实例化点。您所看到的是编译器仅在 CacheImpl
/F
完成后才实例化 make_unique
。允许编译器执行此操作。如果您依赖它,则您的代码格式不正确,并且不需要编译器来检测错误。
14.6.4.1 Point of instantiation [temp.point]
8 A specialization for a function template, a member function template, or of a member function or static data member of a class template may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above, for any such specialization that has a point of instantiation within the translation unit, the end of the translation unit is also considered a point of instantiation. [...] If two different points of instantiation give a template specialization different meanings according to the one definition rule (3.2), the program is ill-formed, no diagnostic required.
关于c++ - Pimpl - 为什么可以在不完整的类型上调用 make_unique,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52180744/