2012-10-16 7 views
5

Ich habe einige Funktionen zu konvertieren, die ich verwende, um eine 2D-Variante SAFEARRAY in verschiedene STL-Container zu konvertieren, ein bisschen wie so (nur illustrativ)Allgemeinfunktionsvariante SAFEARRAY STL-Container

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; 
} 

ich glaube, es ist nicht ein sehr C++ - eine Art und Weise, das zu tun, und es bedeutet, dass es eine separate Funktion für jeden STL-Container gibt, in den ich konvertiere.

Meine Idee war es, einen Wrapper und benutzerdefinierten Iterator für CComSafeArrays zu schreiben, so konnte ich nur tun ...

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

aber habe nie einen Iterator geschrieben vor und ist ein Anfänger ich, wenn es nicht wirklich wissen, wird einfach sein.

Ist ein benutzerdefinierter CComSafeArray-Iterator meine beste, standardmäßige C++ - ähnliche Option (in diesem Fall bin ich sicher, dass ich ein gutes Tutorial zum Schreiben eines Iterators finden kann)? Oder gibt es einen anderen Weg?

Boost ist keine Option.

TIA

Antwort

6

war meine Idee, einen Wrapper und benutzerdefinierten Iterator für CComSafeArrays

Das ist sehr gute Idee, für die Erstellung von Iterator zu schreiben, aber Sie brauchen nicht einen Wrapper um CComSafeArray<T>, nur Iterator wird benötigt.

so konnte ich nur tun ...

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

Doch statt den Weg zu tun, können Sie dies tun:

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

Da fast jeder STL-Container Konstruktor aus Bereich (Paar von Iteratoren).

Angenommen, Sie Iterator über CComSafeArray<T> geschrieben haben - Funktionen beginnen/enden wie diese sein wird:

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()); 
} 

Beachten Sie, dass beginnen() Null-Position, end() ist getSize Position().

Und das Schreiben eines Iterators ist kein Hexenwerk. Nur ein paar Funktionen. Das Wichtigste ist zu wissen, was Sie iterieren müssen. In Ihrem Fall: der Container-Verweis (Zeiger) und die aktuelle Position. Iterieren bewegt nur die Position. Der Zugriff erfolgt über Container und Position. Vergleichen ist über Vergleichsposition.

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; 
}; 
+1

Ihr Iterator ist nicht kopierbar, aber das ist reparierbar, indem Sie 'container' von einer Referenz auf einen Zeiger umschalten. –

+0

@MooingDuck guten Fang, wird behoben – PiotrNycz

+0

Arbeitete wie ein Charme, danke :-) – Sparkles

Verwandte Themen