lundi 4 septembre 2017

Compilation error when passing variadic args to a template function

I have the following template method:

template<typename T, typename... Args>
void register_scene(const std::string& name, Args&&... args) {
    auto func = std::bind(&T::template create<Window*, Args&...>, std::placeholders::_1, std::forward<Args>(args)...);

    _store_scene_factory(name, [=](Window* window) -> SceneBasePtr {
        auto ret = func(window);
        ret->set_name(name);
        return ret;
    });
}

Essentially all I need to do is bind the variadic Args to T::create (which itself is a static variadic template method), but allow populating the first argument (window) separately when it's called.

The above code fails with the following error

error: no match for call to ‘(const std::_Bind<std::shared_ptr<{anonymous}::SceneWithArgs> (*(std::_Placeholder<1>, const char*))(smlt::Window*&, const char (&)[4])>) (smlt::Window*&)’
         auto ret = func(window);
                    ~~~~^~~~~~~~

When calling the code like this:

manager.register_scene<SceneWithArgs>("test", "arg");

I don't really understand the error, or how to fix it.

I initially solved this by simply calling create inside the lambda, and this works on GCC 4.9 and above, but I have to remain compatible with GCC 4.8.4 and there's a bug which prevents using variadic args inside a lambda :(

Aucun commentaire:

Enregistrer un commentaire