c++ - В чем причина cbegin / cend?




3 Answers

Это довольно просто. Скажем, у меня есть вектор:

std::vector<int> vec;

Я заполняю его некоторыми данными. Затем я хочу получить несколько итераторов. Может быть, передать их. Может быть, для std::for_each :

std::for_each(vec.begin(), vec.end(), SomeFunctor());

В C ++ 03 SomeFunctor был свободен, чтобы иметь возможность изменять параметр, который он получает. Конечно, SomeFunctor может принимать свой параметр по значению или const& , но не существует способа обеспечить его выполнение. Не так уж и глупо:

const std::vector<int> &vec_ref = vec;
std::for_each(vec_ref.begin(), vec_ref.end(), SomeFunctor());

Теперь мы вводим cbegin/cend :

std::for_each(vec.cbegin(), vec.cend(), SomeFunctor());

Теперь у нас есть синтаксические заверения, что SomeFunctor не может изменять элементы вектора (конечно, без const-cast). Мы явно получаем const_iterator s, и поэтому SomeFunctor :: operator () будет вызываться с const int & . Если он принимает свои параметры как int & , C ++ выдаст ошибку компилятора.

C ++ 17 имеет более элегантное решение этой проблемы: std::as_const . Ну, по крайней мере, это элегантно, если использовать диапазон:

for(auto &item : std::as_const(vec))

Это просто возвращает const& к объекту, который он предоставил.

Интересно, почему cbegin и cend были введены в C ++ 11?

Каковы случаи, когда вызов этих методов имеет значение от перегрузки const от begin и до end ?




Возьмите это как практическое использование

void SomeClass::f(const vector<int>& a) {
  auto it = someNonConstMemberVector.begin();
  ...
  it = a.begin();
  ...
}

Назначение не выполняется, потому it это инертный неконвертер. Если вы первоначально использовали cbegin, то итератор имел бы правильный тип.




Просто наткнулся на этот вопрос ... Я знаю, что это alredy answerd, и это просто боковой узел ...

auto const it = container.begin() - это другой тип, тогда auto it = container.cbegin()

различие для int[5] (используя указатель, который, как я знаю, не имеет метода begin, но хорошо показывает разницу ... но будет работать в c ++ 14 для std::cbegin() и std::cend() , что по существу то, что нужно использовать, когда оно здесь) ...

int numbers = array[7];
const auto it = begin(numbers); // type is int* const -> pointer is const
auto it = cbegin(numbers);      // type is int const* -> value is const



Related