我可以以非const方式使用Boost.Range索引适配器吗?

时间:2015-06-18 12:21:20

标签: c++ boost

我正在尝试遍历列表,根据共享索引的另一个列表的值更新每个元素。

理想情况下,我希望使用这样的for-range循环:

std::vector<int> is;
std::vector<int> other_list;

for (auto &i : is | boost::adaptors::indexed(0)) {
  i.value() = other_list[i.index()];
}

但我得到的错误是这样的:

indexed.cpp:29:48: error: invalid initialisation of non-const reference of type 'boost::range::index_value<int&, long int>&' from an rvalue of type 'boost::iterator_facade<boost::range_detail::indexed_iterator<__gne_cxx::__normal_iterator<int*, std::vector<int> > >, boost::range::index_value<int&, long int>, boost::random_access_traversal_tag, boost::range::index_value<int&, long in>, long int>::reference {aka boost::range::index_value<int&, long int>}'

我是不是可以使用Boost.Range,或者我只是做错了?

注意:我还尝试使用boost::combine来运气。

1 个答案:

答案 0 :(得分:5)

indexed有点好笑,因为它为您提供了一个范围,其元素包含value()index(),而不是自己的值。关键是你实际上并不需要通过引用来获取indexed元素 - 因为value()本身是可修改的。

例如,如果我要更改Boost提供的示例:

int main(int argc, const char* argv[])
{
    using namespace boost::assign;
    using namespace boost::adaptors;

    std::vector<int> input = {10, 20, 30, 40, 50};
    for (const auto& element : input | indexed(0))
    {
        element.value() = 1;
    }

    for (int i : input) {
        std::cout << i << ' ';
    }

    return 0;
}

element可能是对const的引用,但我仍然可以更改所有值。

但是,如果input属于const范围 - 那么 value()本身就是对const的引用,因此无法编译。正如你所期望的那样。