我可以在输入迭代器上定义开始和结束吗?

Can I define begin and end on an input iterator?

假设我有一个满足 std::input_iterator 概念的输入迭代器类型 MyInputIter(我用它来遍历树状结构)。

为什么我不应该在迭代器本身上定义 begin()end()

struct MyInputIter
{
    // iterator stuff omitted

    auto begin() const { return *this; }
    auto end() const { return MySentinel{}; }
};

原因是我不必创建另一种类型来包装 beginend,所以我可以在 for 循环中使用它:

MyInputIter iterate(TreeNode root, FilterPattern pattern)
{
    return MyInputIter{ root, pattern };
}

void foo()
{
    for (auto item : iterate(someRandomTreeNode, "*/*.bla"))
        process(item);
}

同时还可以将其用作迭代器:

std::vector<TreeNode> vec(iterate(someRandomTreeNode, "*"), MySentinel{});

Are there any reasons why I shouldn't define begin() and end() on the iterator itself?

需要考虑的潜在问题:

  1. 为迭代器实现这些功能可能很昂贵。要么是因为需要遍历结构来找到它们,要么是因为迭代器中存储了额外的状态。
  2. 它可能会造成混淆,因为它偏离了常见的模式。编辑:正如 康桓瑋 所指出的,在 std::filesystem::directory_iterator 范围内的迭代器有先例,所以这通常不是一个重要的问题。还有一个考虑因素是您的范围实现是否以预期的方式工作。

Reason being that I don't have to create another type

据我所知,您不需要创建其他类型。您可以使用:

std::ranges::subrange(MyInputIter{ root, pattern }, MySentinel{})