Krystex
Krystex

Reputation: 167

C++: How call a function with type parameter on variadic template arguments?

So I have a function with variadic template arguments and I'm trying to invoke a method (with a type parameter) for every argument, pack every result value in a std::tuple and return it. However variadic templates are pretty hard for me and I haven't fully understood them yet.

Is it even possible to realize this in C++?

Here's my code so far (which has an error in the getMultiple function). Thank you very much for helping!

#include <iostream>
#include <fstream>
#include <sstream>

template<typename T>
T get(std::istream &stream) {
    T data;
    stream >> data;
    return data;
}

template<typename ... Ts>
std::tuple<Ts...> getMultiple(std::istream &stream) {
    // What am I doing wrong here?
    return std::make_tuple((get<Ts...>(stream)));
}

int main() {
    std::istringstream stream("count 2");
    auto [command, number] = getMultiple<std::string, int>(stream);

    return 0;
}

Upvotes: 6

Views: 860

Answers (2)

Jarod42
Jarod42

Reputation: 218323

You are nearly correct, but your ... are misplaced,

get<Ts...>(stream) translates to get<T0, T1, .., Tn>(stream)

it would be

foo(get<Ts>(stream)...) which translate to foo(get<T0>(stream), get<T1>(stream), .., get<Tn>(stream))

and you have issue with evaluation order

in foo(a(), b()), a() and b() are indeterminately sequenced, so a() might happens before b(), or the reverse. variadic template doesn't change that.

So you cannot use std::make_tuple. Fortunately inside {..}, order is determined from left to right, so you might use:

return std::tuple{get<Ts>(stream)...};

Upvotes: 3

Sam Varshavchik
Sam Varshavchik

Reputation: 118435

First of all, you forgot the

#include <tuple>

And the syntax you're probably looking for is:

return std::make_tuple(get<Ts>(stream)...);

Upvotes: 4

Related Questions