1

Basically I have a variadic template function like so:

template<typename... Args>
void foo(std::string message, Args... args) {
    //Some nice code
}

I now wanted to have a struct, which stores the values, which I use later to call this function. I tried it like this:

template<typename... Args>
struct Foo {
    std::string message;
    Args args;

    Foo(std::string message, Args... args): message(message), args(args) {}
}

int main(int arg, char ** argv) {
    Foo arguments("Hello, World!", 5, "LOL");

    foo(arguments.message, arguments.args);

    return 0;
}

But unfortunately this doesn't work. Is this somehow doable?

Josef Zoller
  • 921
  • 2
  • 8
  • 24

1 Answers1

3

Member packs are not allowed yet in C++. You'll have to resort to use something like a tuple, and re expand the pack when using it:

template<typename... Args>
struct Foo {
    std::string message;
    std::tuple<Args...> args;

    Foo(std::string message, Args&&... args) :
        message(message), args(std::forward<Args>(args)...) {}
    //                         ^
    // I added perfect forwarding to reduce copies
}

Then to transform the tuple into a pack again, you can use std::apply:

std::apply(
    [&](auto&&... args) {
        foo(arguments.message, args...);
    },
    arguments.args // this is the tuple, not a pack
);
Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
  • This would be an opportunity for perfect forwarding. Ex : `Foo(Args&&... args) : args(std::forward(args)...)`. See [this question](https://stackoverflow.com/questions/3582001/advantages-of-using-forward). – François Andrieux Apr 18 '19 at 17:23
  • Yeah I know, I did not wanted to change the code much, but it may be worth it – Guillaume Racicot Apr 18 '19 at 17:24
  • So std::apply exists only since C++17, right? What can I do, if I want to support earlier versions? – Josef Zoller Apr 18 '19 at 17:25
  • You can find implementations, C++14 has the required building blocks for that – Guillaume Racicot Apr 18 '19 at 17:26
  • Thank you, that works. Unfortunately I realized, that such a struct does not fit for my project, because it would have been a derived struct, and so I would have to write the pointer conversions explicit with the variadic templates (I don't know, if this is understandable XD). So my question was basically useless for me. – Josef Zoller Apr 18 '19 at 18:39