我之前没有实现过基于范围的机制,并且很好奇这对于SAFEARRAY是如何工作的。
可能的用例是希望从std::vector
填充SAFEARRAY *
。您是否需要将SAFEARRAY
包装在提供特殊迭代器的自定义类中?
一个问题是SAFEARRAY
可以包含不同的类型。假设你映射了字符串< - > BSTR,int< - > I4和所有其他类型无效,你怎么能设置像for(string s : MySafeArray)
?
我们已经有了一个包装类:template <class T> SafeArrayWrapper{...}
其中T
是您希望数组内容被视为的类型。
答案 0 :(得分:2)
嗯,尊重从SAFEARRAY枚举字符串或整数的能力的最简单方法是创建两个集合类,一个用于表示字符串,另一个用于表示整数,用于安全阵列。
这可能代表一个可枚举的字符串集合。
class SafeArrayStringList {
public:
SafeArrayStringList(SAFEARRAY);
class iterator;
iterator begin();
iterator end();
};
对此至关重要的是迭代器的(前向)声明,以及a()和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;
}
答案 1 :(得分:0)
您需要创建:
支持operator*
,operator++
和operator!=
重载的迭代器。将其设为std::itertor
函数begin(SAFEARRAY&)
和end(SAFEARRAy&)
及其const
版本。
这是一个人为的例子,展示了为用户定义的类型支持范围 - 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;
}