0
votes

I have the following structure that lets me bind the virtual functions of ExampleInterfaceClass to a class that implements the virtual functions from ExampleInterfaceClass:

struct ExampleStruct {
    ExampleInterfaceClass *instance = nullptr;

    ExampleInterfaceClass *(*InstantiateScript)(void);
    void (*DestroyScript)(ExampleStruct *);

    template <typename T> void Bind(void)
    {
        InstantiateScript = []()
        {
            return static_cast<ExampleInterfaceClass *>(new T());
        };

        DestroyScript = [](ExampleStruct *exampleStruct)
        {
            delete exampleStruct->instance;
            exampleStruct->instance = nullptr;
        };
    }
};

Now I want to forward variadic arguments from Bind() to the instantiation of the class that implement the interface. I know I have to change the template to the following

template <typename T, typename... T_args> void Bind(T_args &&... args)

But I have trouble to pass the variadic arguments to the instantiation of the class because of the lambda. Without the lambda I think I could use the following:

return static_cast<ExampleInterfaceClass *>(new T(std::forward<T_args>(args)...));

But the compiler tells me that 'args' are not captured.

How can I capture the variadic arguments and forward them?

1
Have you tried using a default-capture of =? - Sam Varshavchik
@SamVarshavchik - capturing the arguments, the lambda can't be assigned to a function pointer anymore. - max66
@max66 Even with =? That does a copy. - Anonymous1847
Correct. Must use std::function. - Sam Varshavchik
@SamVarshavchik Add answer? - Anonymous1847

1 Answers

3
votes

You can capture variadic arguments in the same way you would capture any other arguments. However, care must be taken to not capture them by value, as it will make them const qualified. Here is an example:

#include <utility>

struct L {};
void k(L&& );

template<class... T> void foo(T&&... t)
{
    auto l = [&t...]() { k(std::forward<T>(t)...); };
}

void a()
{
    L l{};
    foo(l); // errror
    foo(L{}); // OK
}

Please note, once you start capturing in lambda (no matter how), it is no longer convertible to function pointer and you'd have to store it in std::function object if you need to type-erase it.