问题
It seems natural to have an std::iterator
for std::tuple
. However it is not implemented, so programmers implement there own versions. One is for example found at Jonathan Müller's Blog.
Do I overlook something? Is there any reason why there is no "official version" for an tuple_iterator?
回答1:
std::tuple
is not a container, at least not in the sense of the standard library containers. It cannot be iterated with the usual methods because it holds objects of different types. Standard containers are homogenous containers, while std::tuple
is a heterogeneous container.
This doesn't mean that you can't iterate over a tuple, but it's very cumbersome and you can't use the established syntax:
Let's imagine you want to iterate over a tuple the same way you iterate over a container like std::vector
:
std::tuple<int, std::string, bool> t = {...};
for (auto it = t.begin(); it != t.end(); ++it)
{
auto elem = *it; // this cannot work the same way as with containers
// because each element is of a different type
}
There are a couple of things you could do. Use an iterator who holds a std::variant
with the types of the container. Accessing the true object underneath is not as easy. And also this kind of iterator wouldn't be usable anywhere else in the standard library where an iterator is expected, at least not without some extra work.
Also there is work on a proposal for metaprogramming (reflexion, introspection) that has (or had, hadn't followed it) the following syntax:
std::tuple<int, std::string, bool> t = {...};
// something like this (can't remember the syntax exactly):
for constexpr ... (auto elem : t)
{
// only the common set of operations permitted with `elem`
// e.g. this is valid
std::cout << elem << std::endl;
// this is invalid:
//elem.size();
}
This would actually be unrolled at compile time resulting in the following code:
std::tuple<int, std::string, bool> t = {...};
{
int elem = std::get<0>(t);
std::cout << elem << std::endl;
}
{
std::string elem = std::get<1>(t);
std::cout << elem << std::endl;
}
{
bool elem = std::get<2>(t);
std::cout << elem << std::endl;
}
来源:https://stackoverflow.com/questions/61345033/is-there-any-reason-why-there-is-no-stditerator-for-stdtuple-in-c