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.