强制foreach使用const迭代器

时间:2013-11-12 21:25:24

标签: c++ c++11 iterator containers

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

for (const auto val: container)

并且像这样:

for (auto const val: container)

并且像这样:

for (const auto const val: container)

是否有可能强迫foreach使用常数c函数?

3 个答案:

答案 0 :(得分:10)

确定:使范围看起来好像是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()成员。

答案 1 :(得分:6)

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

答案 2 :(得分:1)

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

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

如果没有新函数,你只能在这里得到非const迭代器(或插入一个非常笨拙的演员)。