我正在混合一些C和C ++库,只有一个指针可用于在回调函数中做一些工作。我需要做的就是遍历一个向量。这是一个简单的未经测试的例子:
bool call_back(void* data){
done=...
if (!done) cout << *data++ << endl;
return done;
}
请注意,此函数位于C ++的extern "C"
块中。将调用call_back
,直到返回true。我想让它在每次调用它时都会输出下一个元素。 data
是指向我可以从代码中的其他地方传递的东西的指针(上例中的迭代器,但可以是任何东西)。来自data
的内容可能会用于计算done
。我看到两个明显的选项可以提供给data
:
data
指向我的矢量。data
指向我向量的迭代器。如果没有.end()方法,我不能使用迭代器,对吗?我不能单独使用矢量(除非我可能开始删除它的数据)。我可以使用vector和iterator创建一个struct,但是有更好的方法吗?你会做什么?
答案 0 :(得分:3)
为什么不将数据指向具有您需要的所有信息的结构。
关于旧“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;
}
答案 1 :(得分:1)
如果没有.end()方法,我不能使用迭代器,对吗?
没有。您可以使用迭代器来调用.end()函数。你不需要继续调用.end()函数......所以如果你只存储两个迭代器,那么你就是黄金。
我不能单独使用矢量(除非我开始删除它的数据)。
不是唯一的,但是使用std :: size_t索引,那就是你需要的全部内容。
我可以使用vector和iterator创建一个结构,但是有更好的方法吗?你会做什么?
如果您不必担心支持其他容器类型,那么我会使用:
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
,但我个人认为只需创建一个自定义结构来保存这些信息就更具可读性。
答案 2 :(得分:0)
如何取消引用迭代器并将其值传递给call_back
?然后在函数返回后递增它?