我以前没有实现过基于范围的for机制,我很好奇这对于SAFEARRAY是如何工作的。
一种可能的用例是希望从SAFEARRAY *填充std::vector。例如,您是否需要将SAFEARRAY包装在提供特殊迭代器的自定义类中?
一个问题是SAFEARRAY可以包含不同的类型。假设您映射的字符串<--> BSTR、int <--> I4和所有其他类型都无效,如何设置如下内容:for(string s : MySafeArray)
我们已经有了一个包装类:template <class T> SafeArrayWrapper{...},其中T是您希望将数组内容视为的类型。
发布于 2015-10-23 22:04:47
要实现从safearray枚举字符串或整数的能力,最简单的方法是创建两个集合类,一个用来表示字符串,另一个用来表示SAFEARRAY中的int。
下面是可能表示字符串的可枚举集合的内容。
class SafeArrayStringList {
public:
SafeArrayStringList(SAFEARRAY);
class iterator;
iterator begin();
iterator end();
};至关重要的是迭代器的(转发)声明,以及being()和end()方法,当您在其中一个循环上使用基于范围的for循环时,C++将查找该方法。
迭代器的定义如下所示:
class SafeArrayStringList::iterator {
SAFEARRAY _array;
int _idx;
public:
iterator(SAFEARRAY);
iterator& operator++();
bool operator!=(const iterator& rhs);
std::string operator*();
};这几乎就是你所需要的(在XCode上),以满足基于范围的for循环的需求。
如果操作得当,您应该让迭代器扩展std::iterator类,但为了清楚起见,我去掉了实际上不需要的所有内容。
要枚举SAFEARRAY中的字符串,您需要
for(auto stringitem : SafeArrayStringList(safeArray){
std::string foo = *stringitem;
} 发布于 2015-10-23 21:57:30
您需要创建:
operator*、operator++和operator!=重载的迭代器。使其成为std::itertorbegin(SAFEARRAY&)和end(SAFEARRAy&)及其const变体的子类型。下面是一个人为设计的示例,它展示了您需要为用户定义的类型支持range-for。
#include <vector>
#include <iterator>
struct Foo
{
std::vector<int> vec_;
};
struct FooIterator : std::iterator<std::forward_iterator_tag, int>
{
FooIterator(Foo& f) : foo_(f), iter_(f.vec_.begin()) {}
FooIterator& end() { iter_ = foo_.vec_.end(); return *this; }
int& operator*() { return *iter_; }
std::vector<int>::iterator operator++() { return ++iter_; }
bool operator!=(FooIterator const& rhs) const { return iter_ != rhs.iter_; }
Foo& foo_;
std::vector<int>::iterator iter_;
};
FooIterator begin(Foo& foo)
{
return FooIterator(foo);
}
FooIterator end(Foo& foo)
{
return FooIterator(foo).end();
}
int main()
{
Foo foo;
for ( auto f : foo )
{
}
return 0;
}https://stackoverflow.com/questions/33303997
复制相似问题