Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Templates 在STL映射中存储通用std::函数?_Templates_C++11_Lambda_Std Function - Fatal编程技术网

Templates 在STL映射中存储通用std::函数?

Templates 在STL映射中存储通用std::函数?,templates,c++11,lambda,std-function,Templates,C++11,Lambda,Std Function,我有一组委托工厂,使用不同的参数定义为lambda,即: std::function<Mesh*()> f1 = [&]() -> Mesh * {return new Mesh();}; std::function<Image*(const std::string&)> f2 = [&](const std::string& path) -> Image * {return new Image(path);}; std::fu

我有一组委托工厂,使用不同的参数定义为lambda,即:

std::function<Mesh*()> f1 = [&]() -> Mesh * {return new Mesh();};
std::function<Image*(const std::string&)> f2 = [&](const std::string& path) -> Image * {return new Image(path);};
std::function<VertexBuffer*(VertexBuffer::eType, int, int)> f3 = [&](VertexBuffer::eType type, int size, int count) -> VertexBuffer * {return new VertexBuffer(type, size, count);};
通过这些委托,我可以用不同的参数列表创建不同的对象类型。这些委托应该由特定的IOC容器类处理,该类使用std::type作为键将它们存储在单个STL映射中,以确定应该调用哪个委托

我怎么能把这个存档?使用std::function void指针是不可能的,同时我还需要为这些functor定义的参数。我还试图为这些委托定义一个模板类作为工厂,但我没有找到解决方案,即如何为这个工厂定义一个接口,它包含一个调用委托的纯虚拟方法

template<class T, typename ... Args>
class DelegateFactory
{
public:
    std::shared_ptr<T> create(Args&& ... args) const {
        return std::shared_ptr<T>(static_cast<T*>(m_delegate(std::forward<Args>(args)...)));
    }

    void registerDelegate(std::function<T* (Args&& ... args)> delegate)
    {
        m_delegate = delegate;
    }   

private:    
    std::function<T* (Args&& ... args)> m_delegate = nullptr;
};

这看起来像是boost::any和boost::any_映射的一个例子。但是我不能用boost。有没有一个纯粹的基于c++11的解决方案来解决这个问题。还是几乎不可能?

< p>创建一个容器,动态存储任意委托,其中每个委托可以在C++中使用任意的参数集。至少如果您不想删除所有类型信息,这将给您留下一个相当庞大的工厂,尤其是没有boost的支持

但是,如果您可以使用一组受支持的静态类,那么您可以创建一个工厂来保存这些类的运行时指定的委托:

template <class... Signatures>
class DelegateFactory
{
    // tuple storing our delegates
    typedef std::tuple<std::function<Signatures>...> tuple_type;
    tuple_type m_delegates;

    // helper template to check if N indexes the delegate for type T
    template<size_t N, class T> 
    using is_index_of_type = std::is_same<T*, typename std::tuple_element<N, tuple_type>::type::result_type>;

    // helper template go get the delegate index for type T
    template<class T>
    struct index_of_type
    {
        template <size_t N, bool IsIndex>
        struct impl
        {
            // not the correct index, try the next one
            static const size_t value = impl<N + 1, is_index_of_type<N + 1, T>::value>::value;
        };

        template <size_t N>
        struct impl < N, true >
        {
            // this is the correct index
            static const size_t value = N;
        };

        static const size_t value = impl<0, is_index_of_type<0, T>::value>::value;
    };

public:
    template <class T, class F>
    void register_delegate(F functor)
    {
        // put it into the tuple
        std::get<index_of_type<T>::value>(m_delegates) = functor;
    }

    template <class T, class... Args>
    std::unique_ptr<T> create(Args... args)
    {
        // call the delegate with the given arguments and put the pointer into a unique_ptr
        return std::unique_ptr<T>{ std::get<index_of_type<T>::value>(m_delegates)(std::forward<Args>(args)...) };
    }
};

实例:

谢谢你的建议。我得试试。我的问题是,我必须在容器类中使用委托。有没有一种方法可以将带有任意参数的单个委托存储为类成员,而无需将类模板化以将此类存储在STL容器中?