【问题标题】:Getting a list iterator via reference to an element in the list通过引用列表中的元素获取列表迭代器
【发布时间】:2017-03-24 13:59:15
【问题描述】:

在 C++ 编码中: 假设我有一个函数,它返回对某个列表中元素的引用(我无法更改返回类型或函数的作用)。 有什么方法可以通过返回的 reference 让我获得 iterator 到该列表中的特定元素? 谢谢, 罗伊

【问题讨论】:

  • 被引用的对象不知道它是列表的一部分
  • 看看std::find
  • 如果您无权访问列表本身,则没有。如果你这样做,你可以std::find列表中的元素。

标签: c++ list reference iterator listiterator


【解决方案1】:

仅当您有权访问该列表时。如果您仍然打算使用迭代器,这应该是给定的。

您将不得不再次迭代列表,并检查迭代器返回的每个元素,直到匹配给定的引用。

【讨论】:

    【解决方案2】:

    好吧,你可以用不安全的方式来做,假设std::list<T>::iterator被实现为一个指向列表节点的指针。基本上,您需要调整值的地址以获取封闭列表节点的地址,这将是迭代器的值。

    实际代码(在 mac 上使用 gcc 和 clang):

    // Offset may vary for different Ts
    template <typename T>
    std::ptrdiff_t list_node_payload_offset() {
        std::list<T> lst;
        lst.push_back(T{});
        auto lst_begin = lst.begin();
        return reinterpret_cast<uint8_t*>(std::addressof(lst.front())) -
            *reinterpret_cast<uint8_t**>(std::addressof(lst_begin));
    }
    
    #pragma GCC optimize "no-strict-aliasing"
    template <typename T>
    typename std::list<T>::iterator to_list_iterator(T& t) {
        static const auto offset = list_node_payload_offest<T>();
        auto node_address = reinterpret_cast<uint8_t*>(std::addressof(t)) - offset;
        return *reinterpret_cast<typename std::list<T>::iterator*>(&iter_value);
    }
    #pragma GCC optimize "strict-aliasing"
    

    On Coliru

    【讨论】:

      猜你喜欢
      • 2013-12-03
      • 1970-01-01
      • 1970-01-01
      • 2022-10-23
      • 1970-01-01
      • 1970-01-01
      • 2014-05-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多