Search code examples
c++templatesvariadic-templates

How to call variadic template function with defined first parameter through std::apply?


I'm relatively new to parameter packs, but I want to build a class that receives argument pack, collects values that are contained within and launches them into another function.

I have a class that has variadic template and a function which assigns values. Function is taking arguments from VARIANT structure.

Unwrapper Function:

 template <typename...Args>
    constexpr void ValuesFromValuesVariant(VARIANT variant, Args&...args)
    {
        static std::size_t nArgs = sizeof...(Args);
        if (!nArgs) return;
        auto vArray = GetArray(variant, nArgs);

        auto i = 0u;
        GetNextItem(vArray, i, args);
    }

Class that uses it:

template <class ...Args>
class Receiver
{
    using SendFunction = std::function<HRESULT(Args...)>;
    using InterruptFunc = std::function<HRESULT()>;
    ...
    virtual HRESULT OnSend(VARIANT params)
    {
        //Here I'd like to call it with a VARIANT, but I can't for some reason
        std::apply(ValuesFromValuesVariant, params, std::tie(arguments)); //std::tie to get refs& to the arguments

        HRESULT hr = std::apply(m_Function, arguments);
        return hr;
    }
private:
    InterruptFunc m_InterruptFunc;
    SendFunction m_Function;
private:
    std::tuple< Args... > arguments;
};

I've tried to std::bind a first function parameter, but it can't automatically predict what arguments it's taking, VariantCommunication::ValuesFromValuesVariant<Args> specifier does not work.


Solution

  • To use apply with extra arguments than tuple, you might capture it in the functor:

    std::apply([&](auto&... args){ ValuesFromValuesVariant(params, args...); }, arguments);
    

    or concat extra parameter to the tuple:

    std::apply(&ValuesFromValuesVariant, std::tuple_cat(std::tie(params), arguments));