具有boost :: factory的AbstractFactory模式,无法找出解决方案

时间:2018-09-10 17:27:49

标签: c++11 boost-bind abstract-factory boost-function boost-functional

我正在尝试实现一个抽象的工厂类,该类使用boost :: factory。与这篇文章https://meetingcpp.com/blog/items/building-factories-in-cplusplus.html类似,但是,我希望工厂通过模板来抽象。我还希望抽象工厂为单例,这就是Singleton.hh标头提供的内容(这是正常的Singleton模式,没什么特别的。)

理想情况下,这将支持ManufacturedType的任意数量的构造函数参数,但是我只是想让它仅与1个强制构造函数参数一起使用(这很容易与默认的可构造类一起使用,但是我无法获得此参数为1个参数工作,更不用说“任何”数量的参数了。

当我尝试使用工厂时,就像这样:

static RegisterInFactory<Base, Foo, std::string, boost::function<Foo*(std::unique_ptr<Base::Options>)>> registerByName("Foo");

我收到以下错误:

boost/1.66.0/include/boost/bind/bind.hpp:249:41: error: no match for call to '(boost::factory<Foo*, void, (boost::factory_alloc_propagation)0u>) (std::unique_ptr<Base::Options>)'
         return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_]);
                                         ^
compilation terminated due to -Wfatal-errors.

模板源代码:

#include "Singleton.hh"
#include <map>
#include <string>
#include <boost/bind.hpp>
#include <boost/functional/factory.hpp>
#include <boost/function.hpp>

template <
  class T_ManufacturedType,
  typename T_ClassIDKey = std::string,
  typename T_CreateFn = boost::function<typename std::remove_pointer<T_ManufacturedType>::type*()>>
class AbstractFactory : public Singleton<AbstractFactory<T_ManufacturedType, T_ClassIDKey, T_CreateFn>>
{
    friend class Singleton<AbstractFactory>;
    using ManufacturedType = typename std::remove_pointer<T_ManufacturedType>::type;

public:
    static void RegCreateFn(const T_ClassIDKey& f_className, const T_CreateFn&    f_fn)
    {
        m_registry[f_className] = f_fn;
    }

template <typename ...T_Args>
    static T_ManufacturedType* Create(const T_ClassIDKey&  f_className, T_Args&&... f_args)
    {
        const auto iter = m_registry.find(f_className);                             // locate the creation function
        return (m_registry.end() != iter) ? iter->second(std::forward<T_Args>(f_args)...) : nullptr; // invoke the creation function
    }

private:
    AbstractFactory() = default;
    // Use these declarations to prohibit the compiler from manufacturing default methods.
    AbstractFactory(const AbstractFactory&) = delete;
    AbstractFactory& operator=(const AbstractFactory&) = delete;

    static std::map<T_ClassIDKey, T_CreateFn>  m_registry;
};

template <class T_ManufacturedType, typename T_ClassIDKey, typename T_CreateFn>
std::map<T_ClassIDKey, T_CreateFn> __attribute__((init_priority(101))) AbstractFactory<T_ManufacturedType, T_ClassIDKey, T_CreateFn>::m_registry;

template <
  class T_AncestorType,
  class T_ManufacturedType,
  typename T_ClassIDKey = std::string,
  typename T_CreateFn = boost::function<typename std::remove_pointer<T_ManufacturedType>::type*()>>
class RegisterInFactory
{
    using ManufacturedType = typename std::remove_pointer<T_ManufacturedType>::type;

public:
    RegisterInFactory(const T_ClassIDKey&  f_id)
    {
        AbstractFactory<T_AncestorType, T_ClassIDKey, T_CreateFn>::Instance().RegCreateFn(f_id, boost::bind(boost::factory<ManufacturedType*>(), _1));
    }
};

0 个答案:

没有答案