设置<shared_ptr <t>&gt; :: iterator以设置<shared_ptr <t const =“”>&gt; :: const_iterator

时间:2018-03-16 15:19:33

标签: c++ iterator type-conversion const

所以我见过questions about casting std::shared_ptr<T> to std::shared_ptr<T const>,到目前为止效果还不错。但我有另一个问题。我想将一个交互者返回到我的std::set<std::shared_ptr<T>>,其中Tstd::shared_ptr都是常量。我无法将它们直接转换为任何演员。我收到以下错误:

error: no viable conversion from returned value of type
'_Rb_tree_const_iterator<shared_ptr<tuple<...>>>' to function return type
'_Rb_tree_const_iterator<shared_ptr<const tuple<...>>>'
      return ptrLut.begin();
             ^~~~~~~~~~~~~~

我看到的一个解决方法是存储union std::set<std::shared_ptr<T>>std::set<std::shared_ptr<T const>>,但我觉得这可能不是解决此问题的正确方法。我只是想知道是否有一个很好的方法来做这个演员?

2 个答案:

答案 0 :(得分:0)

set<A>set<B>无关,即使A可隐式转换为B,因此您无法获得来自set<shared_ptr<T const>>::const_iterator的{​​{1}}。

你可以做的最好的事情就是使用boost::transform_iterator这样的东西,它具有添加常量的功能。除非迭代器要求 set<shared_ptr<T>>::iterator,否则只需具有与

相同的行为,这就足够了

E.g。

set<shared_ptr<T const>>::const_iterator

答案 1 :(得分:0)

对于其他任何人:经过几天的思考,这就是我提出的解决方案。

用于保存真实迭代器的Iterator类模板,不允许任何人触摸它。

template<typename It>
struct Iterator {
  Iterator(It &&it) : setIt(it) { }

  Iterator &operator++() {
    ++setIt;
    return *this;
  }

  T const &operator*() {
    return **setIt;
  }

  bool operator==(Iterator<It> const &other) {
    return setIt == other.setIt;
  }

  bool operator!=(Iterator<It> const &other) {
    return setIt != other.setIt;
  }

  std::shared_ptr<T const> ptr() {
    return *setIt;
  }
private:
  It setIt;
};

然后简单地做

auto begin() const {
  return Iterator<typename std::set<std::shared_ptr<T>>::iterator>(ptrLut.begin());
}

auto end() const {
  return Iterator<typename std::set<std::shared_ptr<T>>::iterator>(ptrLut.end());
}