简体   繁体   English

通过std :: function调用std:make_shared

[英]calling std:make_shared via a std::function

I have build a factory pattern using new C++11 features. 我使用新的C ++ 11功能构建了工厂模式。 To achieve this a std::function is registered in the registry. 为此,在注册表中注册了std :: function。 Now I am trying to implement the instantiation part. 现在我正在尝试实现实例化部分。 Right now it is implemented like this: 现在它实现如下:

std::map<uint32_t, std::function<Class*()>>::iterator it = m_creators.find(id);
if(it != m_creators.end())
{
    return std::shared_ptr<Class>((it->second)());
}

The problem is, that is is obviously not exception save and I am trying to replace the std::shared_ptr call with a equivalent std::make_shared call. 问题是,这显然不是异常保存,我试图用等效的std :: make_shared调用替换std :: shared_ptr调用。 The std::function is a create function that only calls the constructor of a Object subclass. std :: function是一个create函数,只调用Object子类的构造函数。 The problem is that I have no idea how to use the std::function instead of the call to the constructor in std::make shared. 问题是我不知道如何使用std :: function而不是std :: make shared中对构造函数的调用。 Is this even possible? 这甚至可能吗?

I would make the std::function return a shared_ptr rather than a naked pointer. 我会让std :: function返回一个shared_ptr而不是一个裸指针。 Then you could use make_shared inside the std::function. 然后你可以在std :: function中使用make_shared。

typedef std::map<uint32_t, std::function<std::shared_ptr<Class>()>> CreatorMap;
CreatorMap::iterator it = m_creators.find(id);
if(it != m_creators.end())
{
    return (it->second)();
}

// example of a creator

struct SomeCreator{
public:
    std::shared_ptr<Class> operator()(){
        return std::make_shared<Class>();
    }
}

this also allows more flexibility to allow the factory to use custom deleter. 这也允许工厂更灵活地使用自定义删除器。

The code you have is not exception unsafe. 您拥有的代码不是不安全的例外。 The shared_ptr constructor that takes a pointer will call delete on the managed pointer if an exception occurs during initialization. 如果在初始化期间发生异常,则获取指针的shared_ptr构造函数将在托管指针上调用delete

From N3797, §20.8.2.2.1/7 从N3797, §20.8.2.2.1/ 7

template<class Y> explicit shared_ptr(Y* p);
... ...
Exception safety: If an exception is thrown, delete p is called. 异常安全:如果抛出异常,则调用delete p

If it makes you feel better, you could change the map type to 如果它让您感觉更好,可以将map类型更改为

std::map<uint32_t, std::function<std::unique_ptr<Class>()>>

shared_ptr s can be constructed from unique_ptr s, and you're never passing around a raw pointer in this case. shared_ptr可以从unique_ptr构造,在这种情况下你永远不会传递原始指针。 But it is unnecessary because of the clause I quoted above. 但由于我在上面引用的条款,这是不必要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM