boost zip_iterator игнорирует правильность констант

В течение цикла внутри main() функция следующего кода, я могу изменить переменные внутри переменной ab даже когда const auto& используется в цикле. Есть ли способ избежать этого?

#include <functional>
#include <iostream>
#include <vector>
#include <string>

#include <boost/iterator/zip_iterator.hpp>
#include <boost/tuple/tuple.hpp>

using namespace std;

struct MyClass {
  std::vector<int> a{11, 21, 41};
  std::vector<int> b{1, 2, 4};
  typedef boost::zip_iterator<boost::tuple<std::vector<int>::const_iterator, std::vector<int>::const_iterator>> const_iterator;
  typedef boost::zip_iterator<boost::tuple<std::vector<int>::iterator, std::vector<int>::iterator>> iterator;

  const_iterator begin() const {
    return const_iterator(boost::make_tuple(a.cbegin(), b.cbegin()));
  }
  const_iterator end() const {
    return const_iterator(boost::make_tuple(a.cend(), b.cend()));
  }
  iterator begin() {
    return iterator(boost::make_tuple(a.begin(), b.begin()));
  }
  iterator end() {
    return iterator(boost::make_tuple(a.end(), b.end()));
  }
};


int main(int argc, char** argv)  
{
  MyClass myc;
  for (const auto &ab: myc)
    ab.get<0>() = 66;
  return 0;
}

2 ответа

Решение

Если вы перебираете const MyClass тогда вы получите ошибку компиляции, которую вы хотите:

for (const auto &ab: const_cast<MyClass const&>(myc))
    ab.get<0>() = 66;

Ты можешь использовать std::as_const вместо const_cast:

for (const auto &ab: std::as_const(myc))
    ab.get<0>() = 66;

Это работает, потому что const перегрузки begin а также end будет вызываться вместо, и они возвращают zip_iterator константных итераторов.

Ваша проблема в том, что myc не является константой, поэтому вы перебираете его с myc::iteratorне myc::const_iterator,

Вы тогда связываете ab в результате косвенного через этот итератор. ab.get<0>() будет методом const (потому что он не изменяется ab), но возвращает ссылку на не- const int.

Решение заключается в использовании std::as_const(myc) (где вам даже не понадобится const на декларации ab).

for (auto &ab: std::as_const(myc))
    ab.get<0>() = 66;  // Error.  Cannot write to const object.
Другие вопросы по тегам