我有一堆代表工厂,使用不同的参数定义为Lambdas,即:
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指针是不可能的,而我还需要为这些仿函数定义的参数。我还尝试将模板类定义为这些委托的工厂,但我找不到解决方案,我如何为这个工厂定义一个接口,它包含一个调用委托的纯虚方法。
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_map的情况。但我无法使用提升。是否有基于纯c ++ 11的解决方案来解决这个问题。或者这几乎是不可能的?
答案 0 :(得分:0)
在C ++中创建一个动态存储任意委托的容器,其中每个委托可以接受任意一组参数。至少如果你不想删除所有的类型信息(这会让你的工厂变得非常笨重,特别是没有提升的支持)。
但是,如果您可以使用一组静态的受支持类,则可以创建一个工厂,为这些类保存运行时分配的委托:
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)...) };
}
};