Reputation: 47
This is a simple question, yet the Internet offers no answer or examples to this one:
what is the correct means of passing a parameter pack to a std::tuple
?
I have tried the following, only to find I received the error:
'missing template arguments before token':
#include <tuple>
#include <iostream>
template <typename... Args>
std::tuple <Args...> footup;
template <typename... Args>
void bar(std::tuple <Args...>& footup, Args... args)
{
footup = std::make_tuple(args...);
}
int main()
{
bar(footup, 1, 2, 3, 4, 5, 6, 7);
std::cout << std::get <0>(footup) << " "
<< std::get <1>(footup) << " "
<< std::get <2>(footup) << "\n\n";
return 0;
}
How do I prevent the error message and have the parameter pack work?
Upvotes: 1
Views: 139
Reputation: 33092
How do I prevent the error message and have the parameter pack work?
You should not be passing the variable template footup
directly to the function. You need an instantiated instance of that variable template here. That means,
// Variable template
template <typename... Args> std::tuple <Args...> footup;
// Create a reference to the instantiated variable template "footup" for bar()
auto& footupInstance = footup<int, int, int, int>;
Now, the easiest would be, adding extra template parameter for footupInstance
.
template <typename Tuple, typename... Args>
// ^^^^^^^^^^^^^^^^
void bar(Tuple& footupInstance , Args&&... args)
{
footupInstance = std::make_tuple(std::forward<Args>(args)...);
}
Or do not use the helper bar
, and use the std::make_tuple
directly in the main()
to create the tuple with desired Args...
:
#include <tuple>
int main()
{
/* const */ auto footupInstance = std::make_tuple(1, 2, 3, 4, 5, 6, 7);
// The type of footupInstance (if required).
using MyTupleT = decltype(footupInstance);
}
Upvotes: 3
Reputation: 118097
footup
is a variable template and not an instance variable. You can't pass it around as-if it was an instance.
You could instantiate a variable with it and use that in the call to bar
:
#include <iostream>
#include <tuple>
template <typename... Args>
std::tuple<Args...> footup;
template <class... Args>
void bar(std::tuple<Args...>& instance, Args&&... args) {
instance = std::make_tuple(std::forward<Args>(args)...);
}
int main() {
auto& instance = footup<int, int, int, int, int, int, int>;
// or if you'd like a copy:
// auto instance = footup<int, int, int, int, int, int, int>;
bar(instance, 1, 2, 3, 4, 5, 6, 7);
std::cout << std::get<0>(instance) << ' ' << std::get<1>(instance) << ' '
<< std::get<2>(instance) << '\n';
}
Upvotes: 4
Reputation: 43
I guess what you want is to construct a tuple from a parameter block:
#include <tuple>
#include <iostream>
#include <utility>
template <typename... Args>
std::tuple<Args...> bar(Args&&... args)
{
return std::make_tuple(std::forward<Args>(args)...);
}
int main()
{
auto footup = bar(1, 2, 3, 4);
std::cout << std::get<0>(footup) << " "
<< std::get<1>(footup) << " "
<< std::get<2>(footup) << " "
<< std::get<3>(footup) << "\n";
return 0;
}
Upvotes: 0