5

我有一些函数用于将 2D 变体 SAFEARRAY 转换为各种 STL 容器,有点像这样(仅供说明)

template<typename T>
std::set<T> SetFromSafeArray(VARIANT srcArray)
{
    CComSafeArray<T> srcComArray(srcArray.parray);
    std::set<T> destContainer;

    for (ULONG i=0;i<srcComArray.GetCount();++i)
        destContainer.insert(srcComArray.GetAt(i));

    return destContainer;
}

我觉得这不是一种非常 C++ 的方式,这意味着我转换到的每个 STL 容器都有一个单独的函数。

我的想法是为 CComSafeArrays 编写一个包装器和自定义迭代器,这样我就可以做......

std::copy(srcComArray.begin(), srcComArray.end(), destContainer.begin());

但是以前从未编写过迭代器并且是​​新手,我真的不知道这是否容易。

自定义 CComSafeArray 迭代器是我最好的标准 c++ 选项吗(在这种情况下,我确信我可以找到编写迭代器的好教程)?还是有其他方法可以解决它?

升压不是一种选择。

TIA

4

1 回答 1

6

我的想法是为 CComSafeArrays 编写一个包装器和自定义迭代器

这是创建迭代器的好主意,但您不需要包装器CComSafeArray<T>,只需要迭代器。

所以我可以做...

std::copy(srcComArray.begin(), srcComArray.end(), destContainer.begin());

但是,您可以这样做:

SomeContainer<T> destContainer(begin(srcComArray), end(srcComArray));   

因为几乎每个 STL 容器都有范围内的构造函数(一对迭代器)。

假设您已经编写了迭代器CComSafeArray<T>- 函数开始/结束将如下所示:

template <typename T>
CComSafeArrayIterator<T> begin(CComSafeArray<T>& container)
{
    return CComSafeArrayIterator<T>(container, 0);
}
template <typename T>
CComSafeArrayIterator<T> end(CComSafeArray<T>& container)
{
    return CComSafeArrayIterator<T>(container, container.getSize());
}

注意 begin() 是零位置,end() 是 getSize() 位置。

编写迭代器不是火箭科学。只是几个功能。最重要的是知道你需要迭代什么。在您的情况下:容器引用(指针)和当前位置。迭代只是移动位置。访问是通过容器和位置。比较是通过比较位置。

template <typename T>
class CComSafeArrayIterator {
public:
   CComSafeArrayIterator(CComSafeArray<T>& container, ULONG position) 
   : container(&container), 
   position(position) 
   {}

   // prefix ++it
   CComSafeArrayIterator& operator ++() { ++position; return *this; }
   // postfix it++
   CComSafeArrayIterator operator ++(int) { 
       CComSafeArrayIterator prev = *this; 
       ++position; 
       return prev; 
   }
   // access by ->: it-> !! ony if getAt return reference not value 
   const T* operator -> () const {
      return &(container->getAt(position));
   }
   // access by *: *it
   const T& operator * () const {
      return container->getAt(position);
   }
   // comparing
   friend bool operator == (const CComSafeArrayIterator<T>& l, 
                            const CComSafeArrayIterator<T>& r)
   {
      return l.position == r.position;
   }
   friend bool operator != (const CComSafeArrayIterator<T>& l, 
                            const CComSafeArrayIterator<T>& r)
   {
      return l.position != r.position;
   }



private:
   // this is what you need
   CComSafeArray<T>* container;
   ULONG position;
};
于 2012-10-16T11:48:06.087 回答