我可以在输入迭代器上定义开始和结束吗?
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{}; }
};
原因是我不必创建另一种类型来包装 begin
和 end
,所以我可以在 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?
需要考虑的潜在问题:
- 为迭代器实现这些功能可能很昂贵。要么是因为需要遍历结构来找到它们,要么是因为迭代器中存储了额外的状态。
- 它可能会造成混淆,因为它偏离了常见的模式。编辑:正如 康桓瑋 所指出的,在
std::filesystem::directory_iterator
范围内的迭代器有先例,所以这通常不是一个重要的问题。还有一个考虑因素是您的范围实现是否以预期的方式工作。
Reason being that I don't have to create another type
据我所知,您不需要创建其他类型。您可以使用:
std::ranges::subrange(MyInputIter{ root, pattern }, MySentinel{})
假设我有一个满足 std::input_iterator
概念的输入迭代器类型 MyInputIter
(我用它来遍历树状结构)。
为什么我不应该在迭代器本身上定义 begin()
和 end()
?
struct MyInputIter
{
// iterator stuff omitted
auto begin() const { return *this; }
auto end() const { return MySentinel{}; }
};
原因是我不必创建另一种类型来包装 begin
和 end
,所以我可以在 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?
需要考虑的潜在问题:
- 为迭代器实现这些功能可能很昂贵。要么是因为需要遍历结构来找到它们,要么是因为迭代器中存储了额外的状态。
- 它可能会造成混淆,因为它偏离了常见的模式。编辑:正如 康桓瑋 所指出的,在
std::filesystem::directory_iterator
范围内的迭代器有先例,所以这通常不是一个重要的问题。还有一个考虑因素是您的范围实现是否以预期的方式工作。
Reason being that I don't have to create another type
据我所知,您不需要创建其他类型。您可以使用:
std::ranges::subrange(MyInputIter{ root, pattern }, MySentinel{})