1
\$\begingroup\$

I'm trying to write universal factory creating objects by name. I've got some working prototype now but there must be a better way than casting construction methods to void pointer.

struct aobject {}; // some base

class factory
{
public:
    template <typename... TArgs>
    static aobject *create_named(const char *name, TArgs... args)
    {
        using constructor_t = aobject *(*)(TArgs...);
        auto citer = bindings_.find(name);
        if (citer == bindings_.end())
            return nullptr;
        return ((constructor_t)citer->second)(std::forward<TArgs>(args)...);
    }

    template <class TObject, typename... TArgs>
    static void bind_named(const char *name)
    {
        auto constructor_ptr = (void*)&constructor<TObject, TArgs...>;
        bindings_.insert(std::make_pair(name, constructor_ptr));
    }

private:
    template <class TObject, typename... TArgs>
    static aobject *constructor(TArgs... args)
    {
        return new TObject(std::forward<TArgs>(args)...);
    }

    using obj_name_binding_t = tmap<std::string, void*>;
    static obj_name_binding_t bindings_;
};
}

// TEST
struct test : public aobject {
    test(const char *text) : text_(text) {}
    void foo() { std::cout << text_ << '\n'; }
    const char *text_;
};

factory::bind_named<test, const char*>("test_name");
auto t = static_cast<test*>(factory::create_named("test_name", "text"));
t->foo();

Any ideas?

\$\endgroup\$
  • \$\begingroup\$ Do you have C++17 available? \$\endgroup\$ – hoffmale Aug 11 '17 at 5:52
  • \$\begingroup\$ No, c++14 only... \$\endgroup\$ – Travis Aug 11 '17 at 7:18
  • \$\begingroup\$ Hmm... Unfortunate. With std::any you could simplify your code a lot, but that would require C++17 :/ \$\endgroup\$ – hoffmale Aug 11 '17 at 8:18
  • \$\begingroup\$ Is it same as boost::any? \$\endgroup\$ – Travis Aug 11 '17 at 8:19
  • \$\begingroup\$ I can't change c++ version, it's part of bigger project... \$\endgroup\$ – Travis Aug 11 '17 at 8:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.