I would like to create a std::tuple
from elements in a std::vector
and return it from my function. The size of a std::vector
will not always be three so I need a function that can create a std::tuple
from three, four and more elements and return it.
#include <iostream>
#include <tuple>
#include <vector>
template<typename... Args>
std::tuple<Args...> create_tuple(const std::vector<int>& vec) {
if (vec.size() == 2)
return std::make_tuple(vec[0], vec[1]);
else if (vec.size() == 3)
return std::make_tuple(vec[0], vec[1], vec[2]);
}
int main() {
std::vector<int> vec{ 0, 1, 2 };
auto t = create_tuple(vec);
}
Currently there is a compilation error, so how can I fix it? I am using C++11 and I cannot use 'auto
' as a value type returned from the function.
I would like to create a tuple from elements in vector and return it from my function. The size of a vector will not always be three so I need a function that can create a tuple from three, four and more elements and return it.
Short answer: you can't.
Long answer.
As explained by LogicStuff in a comment, C++ is a statically typed language.
This mean, in your case, that the compiler must known compile time the type returned by create_tuple()
.
Given that the returned type depends from the size()
of the argument, that is known run-time, the compiler can't choose, compile time, the correct return
statement so can't choose the correct returned type.
In other words, the critical point is the body of the function
if (vec.size() == 2)
return std::make_tuple(vec[0], vec[1]);
else if (vec.size() == 3)
return std::make_tuple(vec[0], vec[1], vec[2]);
En passant: if vec.size()
is different from 2
or 3
(1
by example), the compiler don't know what return. But this is a little problem compared to the fact that std::make_tuple(vec[0], vec[1])
and std::make_tuple(vec[0], vec[1], vec[2])
gives different and incompatible types.
So the compiler can't choose if the function return a std::tuple<int, int>
or a std::tuple<int, int, int>
.
This sort of problem can partially solved starting from C++17, with if constexpr
if constexpr (vec.size() == 2)
return std::make_tuple(vec[0], vec[1]);
else constexpr if (vec.size() == 3)
return std::make_tuple(vec[0], vec[1], vec[2]);
else // ???
but also if constexpr
doesn't works because if constexpr
require a test that must be decided compile time and with vec.size()
(where vec
is a std::vector
) is impossible.