强制 foreach 使用常量迭代器

Force foreach to use const iterators

本文关键字:常量 迭代器 foreach 强制      更新时间:2023-10-16

我有一个实现cbegin()cend()函数的自定义容器类。然后我在foreach循环中使用它,但它似乎需要begin()end()成员函数,即使我尝试使用const修饰符:

for (const auto val: container)

像这样:

for (auto const val: container)

像这样:

for (const auto const val: container)

是否可以强制 foreach 使用常数 c 函数?

当然:使范围看起来好像是一个const范围:

template <typename T>
T const& make_const(T const& argument) {
    return argument;
}
// ...
for (auto&& value: make_const(argument)) {
    ...
}

但是,在所有情况下,基于范围的for都将使用begin()end(),并且永远不会cbegin()cend()。您可能希望改为提供以下内容:

template <typename T>
auto begin(my_container<T> const& t) -> decltype(t.cbegin()) {
    return t.cbegin();
}
template <typename T>
auto end(my_container<T> const& t) -> decltype(t.cend()) {
    return t.cend();
}

显然,您希望用合适的容器类型替换my_container。就个人而言,我可能只会提供合适的begin()end()成员。

我不确定仅提供cbegin()cend()的决定是什么,但这些不在基于的范围内使用。如果要在基于 的范围内使用容器,则需要提供begin()end()(尽管您可以让它们返回 const 迭代器)

您应该始终在两个重载(常量和非常量重载)中提供begin()/end()函数。新的cbegin()/cend()函数的目的是允许用auto进行扣除,如下所示:

for (auto it = v.cbegin(); it != v.cend(); ) { /* ... */ }

如果没有新功能,您只能在此处获取非常量迭代器(或插入非常尴尬的强制转换)。