7

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

for (const auto val: container)

像这样:

for (auto const val: container)

像这样:

for (const auto const val: container)

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

4

3 回答 3

10

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

template <typename T>
T const& make_const(T const& argument) {
    return argument;
}

// ...
for (auto&& value: make_const(argument)) {
    ...
}

然而,在所有情况下,基于范围的for将使用begin()andend()而从不使用cbegin()or 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()成员。

于 2013-11-12T21:32:06.993 回答
6

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

于 2013-11-12T21:28:36.680 回答
1

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

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

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

于 2013-11-12T22:44:28.183 回答