代码之家  ›  专栏  ›  技术社区  ›  User1

使用不带容器的迭代器

  •  2
  • User1  · 技术社区  · 14 年前

    我正在混合一些C和C++库,并且只有一个指针可用于回调函数中的一些工作。我需要做的就是迭代一个向量。下面是一个简化的、未经测试的示例:

    
    bool call_back(void* data){
      done=...
      if (!done) cout << *data++ << endl;
      return done;
    }
    

    请注意,此函数位于 extern "C" C++中的块。 call_back 将被调用,直到返回true。我希望它在每次调用下一个元素时都能调用。 data 是指向代码中其他地方可以传递的内容的指针(上面示例中的迭代器,但可以是任何内容)。来自某物 数据 可能用于计算 done . 我看到两个明显的选择 数据 :

    1. 数据 指向我的向量。
    2. 数据 指向向量的迭代器。

    如果没有.end()方法,我就不能使用迭代器,对吗?我不能单独使用向量(除非我开始删除它的数据)。我可以用向量和迭代器构造一个结构,但是有更好的方法吗?你会怎么做?

    3 回复  |  直到 14 年前
        1
  •  3
  •   Loki Astari    14 年前

    为什么不让数据指向一个包含您需要的所有信息的结构呢?

    关于旧的“c”样式回调的要点是void*可以指向任何对象。回调函数知道类型是什么,但它可以是任何类型。

    typedef struct Plop
    {
        std::vector<int>::iterator begin;
        std::vector<int>::iterator end;
    } Plop;
    
    bool call_back(void* data)
    {
        // Or static_cast<> for the pedantic.
        // I like reinterpret_cast<> because it is a clue to humans that this is dangerious
        // and as long as the object was originally a Plop* pointer it is guaranteed to work.
        Plop*   info = reinterpret_cast<Plop*>(data);
    
        bool    done= info.begin == info.end;
    
        if (!done) cout << *data++ << endl;
        return done;
    }
    
        2
  •  1
  •   Michael Aaron Safyan    14 年前

    如果没有.end()方法,我就不能使用迭代器,对吗?

    不可以。可以将迭代器与调用.end()函数的结果一起使用。您不需要一直调用.end()函数…所以如果您只存储两个迭代器,那么您就是黄金。

    我不能单独使用向量(除非我开始删除它的数据)。

    不仅如此,只要有一个std::size_t索引,你就只需要这个了。

    我可以用向量和迭代器构造一个结构,但是有更好的方法吗?你会怎么做?

    如果您不必担心支持其他容器类型,那么我将使用:

     template<typename T> struct CALLBACK_DATA
     {
          std::vector<T>* array;
          std::size_t index;
     };
    

    如果您可能需要支持多种容器类型,那么我将使用:

     template<typename T> struct CALLBACK_DATA
     {
         typedef std::vector<T> container_type;
         typedef typename std::vector<T>::const_iterator const_iterator;
         const_iterator current;
         const_iterator end;
     };
    

    所以,是的,我要么传递向量和索引,要么传递一对迭代器,然后构造一个结构来保存数据。如果希望避免创建结构,则可以使用 std::pair 但是,我个人认为只创建一个自定义结构来保存这些信息更易读。

        3
  •  0
  •   Anthony Atmaram    14 年前

    取消对迭代器的引用并将其值传递给 call_back ?然后在函数返回后递增?