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++ のようなオプションとして最適ですか (その場合、イテレータの作成に関する適切なチュートリアルを見つけることができると確信しています)。それとも何か他の方法がありますか?

ブーストはオプションではありません。

ティア

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>関数 begin/end は次のようになります。

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 に答える