While playing around with variadic templates I came around that:
template <class... Ts> struct tuple {};
template <class T, class... Ts>
struct tuple<T, Ts...> : tuple<Ts...>
{
tuple(T t, Ts... ts) : tuple<Ts...>(ts...), tail(t) {}
T tail;
};
I want just learn to understand what's going on here: We can instantiate such tuple by
tuple<int, double, const char*, const char*, const char*> myTuple(1234, 33.444, "I", "like", "C++");
but not with:
tuple myTuple2(1234, 33.444, "I", "like", "C++");
Why is the compiler not able to infer automatically the types from the list of given types?
If I do
template <class T>
void swap(T& first, T& second) {
T aux = first;
first = second;
second = aux;
}
...
...
swap<int>(a, b);
swap(a, b);
both variants are possible. Is that not possible for variadic template arguments? What are the rules C++ uses for inferring types?
tuple myTuple2(1234, 33.444, "I", "like", "C++");
Is a variable declaration and initialization by calling the constructor, while
swap(a, b);
Is a function call.
While C++ always had function template argument deduction, it didn't support class template argument deduction until C++17. That is the reason why std::make_tuple
exists. Because you couldn't do std::tuple t(1, 2.4)
and so you had a function and could write auto t = std::make_tuple(1, 2.4)
.
So you need C++17 and for your example you also need a deduction guide:
template <class... Ts>
tuple(Ts...) -> tuple<Ts...>;
And it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With