【问题标题】:Is there any reason why there is no std::iterator for std::tuple in c++?c++ 中没有 std::tuple 的 std::iterator 有什么原因吗?
【发布时间】:2020-04-21 22:44:20
【问题描述】:

std::iterator 代表std::tuple 似乎很自然。但是它没有实现,所以程序员实现了自己的版本。例如,可以在Jonathan Müller's Blog 找到一个。

我忽略了什么吗? tuple_iterator 没有“正式版”有什么原因吗?

【问题讨论】:

  • 这些问题的答案总是一样的:没有人提出提案,或者提案被拒绝。
  • std::iterator 只是成员类型的集合,在 C++17 中已弃用。

标签: c++ iterator tuples


【解决方案1】:

std::tuple 不是容器,至少在标准库容器的意义上不是。它不能用通常的方法迭代,因为它包含不同类型的对象。标准容器是同构容器,std::tuple是异构容器。

这并不意味着你不能迭代一个元组,但是它非常繁琐,你不能使用既定的语法:

假设您想以与迭代 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
}

您可以做几件事。使用包含容器类型的 std::variant 的迭代器。访问下面的真实对象并不容易。而且这种迭代器在标准库中需要迭代器的任何其他地方都无法使用,至少在没有一些额外工作的情况下不能使用。

还有一项关于元编程(反射、内省)的提案的工作,该提案具有(或曾经、未遵循)以下语法:

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();
}

这实际上会在编译时展开,从而产生以下代码:

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;
}

【讨论】:

  • 这是正确的,但它可能有助于指出资源解释为什么在 iterator::reference 等方面以及算法如何使用迭代器。
猜你喜欢
  • 2016-06-24
  • 1970-01-01
  • 2016-10-01
  • 2017-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-07
相关资源
最近更新 更多