【问题标题】:boost zip_iterator ignoring const correctness提升 zip_iterator 忽略 const 正确性
【发布时间】:2018-02-22 06:30:57
【问题描述】:

在下面代码的main()函数内的for循环中,即使在循环中使用const auto&,我也可以更改变量ab内的变量。有什么办法可以避免吗?

#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;
}

【问题讨论】:

  • 它无法知道您将这些存储到什么位置。 myc 是非常量的,因此元组将包含非常量迭代器。当与引用的 const 元组一起使用时,使 get 返回不可修改的内容取决于元组类型。它必须不碍事,因为当T 是非常量引用时,const T&amp; 会折叠为相同的非常量引用类型。

标签: c++ boost iterator boost-iterators


【解决方案1】:

如果您遍历 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;

这是因为 beginendconst 重载将被调用,它们返回一个 zip_iterator 的 const 迭代器。

【讨论】:

    【解决方案2】:

    您的问题是 myc 不是 const,因此您使用 myc::iterator 而不是 myc::const_iterator 迭代它。

    然后,您将ab 绑定到通过该迭代器间接进行的结果。 ab.get&lt;0&gt;() 将是一个 const 方法(因为它不会更改 ab),但它返回一个对 non-const int 的引用。

    解决方案是使用std::as_const(myc)(在ab 的声明中甚至不需要const)。

    for (auto &ab: std::as_const(myc))
        ab.get<0>() = 66;  // Error.  Cannot write to const object.
    

    【讨论】:

      猜你喜欢
      • 2012-03-09
      • 2016-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多