2016-07-11 16 views
1

gebe ich den folgenden Code, meine Frage zu veranschaulichen:Wie kann ich Operatoren definieren, so dass ein Array von benutzerdefinierten Typen in ein Array von primitiven Typen umgewandelt werden kann?

#include <vector> 

struct Complex 
{ 
    int a, b, c; 

    Complex() : a(3), b(4), c(10) {} 

    operator int() const { return a+b+c; } 
}; 

int main() 
{ 
    Complex abc; 
    int value = (abc); 
    Complex def; 
    def.a = 20; 
    int value2 = (def); 

    std::vector<Complex> ar; 
    ar.push_back(abc); 
    ar.push_back(def); 

    std::vector<int> ar2; 
    ar2.push_back(abc); 
    ar2.push_back(def); 

    std::vector<int> ar3; 
    ar3 = (ar); 
} 

Dies wird nicht kompilieren, die aufgrund der Expression ar3 = (ar). Ich habe einen Konvertierungsoperator deklariert, so dass die Complex Klasse verwendet werden kann, in der int erwartet wird. Kann ich es auch so einrichten, dass ein Array von Complex Objekten einem Array von int zugewiesen wird?

Ich versuchte, ein nicht-Mitglied Umwandlungsoperator für Array von Complex zu erklären, aber das ist nicht erlaubt:

void std::vector<int> operator = (std::vector<Complex> complexArray) 
{ 
    std::vector<int> abc; 
    for(int i=0; i<complexArray.size(); i++) 
    abc.push_back(complexArray[i]); 
    return abc; 
} 

Antwort

2

Vergessen Sie automatische implizite Konvertierung (zumindest für die Standard-Bibliothek-Container). Aber wenn Sie bereit sind, eine explizite Umwandlung wie im folgenden Beispiel zu akzeptieren

const std::vector<int> vi {1, 2, 3, 4, 5}; 
const std::vector<double> vd = container_cast(vi); 

dann die Umsetzung des container_cast() Dienstprogramm folgt. Man beachte, dass es nicht nur zwischen Instanziierungen desselben Schablonenbehälters für verschiedene Elementtypen (d. H. std::vector<int> bis std::vector<double>), sondern auch zwischen verschiedenen Behältern (z. B. std::vector bis std::list) umwandeln kann.

#include <iostream> 
#include <vector> 
#include <list> 

template<class SourceContainer> 
class ContainerConverter 
{ 
    const SourceContainer& s_; 
public: 
    explicit ContainerConverter(const SourceContainer& s) : s_(s) {} 

    template<class TargetContainer> 
    operator TargetContainer() const 
    { 
     return TargetContainer(s_.begin(), s_.end()); 
    } 
}; 

template<class C> 
ContainerConverter<C> container_cast(const C& c) 
{ 
    return ContainerConverter<C>(c); 
} 

template<class C> 
void printContainer(const C& c) 
{ 
    std::cout << "{ "; 
    for(auto x : c) 
     std::cout << x << ' '; 
    std::cout << "}" << std::endl; 
} 

int main() 
{ 
    const std::vector<double> vd {2.2, 7.7, 5.5, 1.1, -4.4}; 
    printContainer(vd); 

    const std::vector<int> vi = container_cast(vd); 
    printContainer(vi); 

    const std::list<float> lf = container_cast(vd); 
    printContainer(lf); 
    return 0; 
} 
3

Wenn Sie etwas, die std::transform Funktion könnte sein, gut zu bedienen transformieren möchten.

In Ihrem Fall könnte man über so etwas wie

// Create the new vector with the same size as the complex vector 
std::vector<int> abc(complexArray.size()); 

std::transform(std::begin(complexVector), std::end(complexVector), 
       std::begin(abc), 
       [](Complex const& complex) 
       { 
        int result; 

        // Code here that converts the complex structure to an integer 
        // and stores the integer in the variable result 

        return result; 
       }); 

Nach dem std::transform Telefonieren (wenn Sie es mit dem Code vervollständigen, um tatsächlich die Strukturumwandlung zu tun) den Vektor abc alle konvertierten Zahlen von dem enthalten Complex Strukturen im Quellvektor complexVector.

4

Sie können den Bereichserbauer von std::vector betrachten.

std::vector<int> ar3(begin(ar), end(ar)); 
+0

Sie benötigen auch 'using std :: begin; Verwenden Sie std :: end; ', wenn die argumentabhängige Suche die üblichen Funktionen enthalten soll. –