Vector struct



  • Hallo,

    ist es für dich wichtig, dass du nen Vector nutzt? Ansonsten würde ich dir eine List aus dem Namespace System.Collections.Generic empfehlen.



  • Hm, also das hier

    cliext::vector<subject> list();
    

    ist für mich die Deklaration einer Funktion namens List, die einen vector zurückgibt.

    Die beiden Methoden hier gehen

    ref struct Foo
    {
        String^ bar;
    };
    
    int main(array<System::String ^> ^args)
    {
        auto s1 = gcnew Foo;
        Foo s2;
    
        auto v = gcnew cliext::vector<Foo^>;
        cliext::vector<Foo^> v2;
    
        v->push_back(s1);
        v2.push_back(s1);
    
        v->push_back(%s2);
        v2.push_back(%s2);
    
        return 0;
    }
    

    Ob ein vector<Foo> auch geht, also ohne Handle, weiß ich nicht.



  • Danke nn das klappt schonmal super.
    Aber wie bekomme ich jetzt auch wirklich einen String da rein ?

    In normalen C++ würde ich das so realiseren.

    struct subject {
    std::string str;
    std::string value;
    };

    int main ()
    {
    std::vector<subject> list;
    list.push_back(subject());
    list[0].str ="1";
    list[0].value = "test";
    }

    Aber hier jetzt Werte einfügen macht mir Probleme.



  • Das ist eine spannende Frage. Ein cliext::vector hat einen []-Operator, gleichzeitig implementiert er auch IVector, ICollection und IList und hat damit einen Indexer.

    Mit meinem Beispiel von oben

    using namespace System;
    using namespace System::Collections::Generic;
    
    ref struct Foo
    {
        String^ bar;
    };
    
    int main(array<System::String ^> ^args)
    {
        auto s1 = gcnew Foo;
        Foo s2;
    
        auto v = gcnew cliext::vector<Foo^>;
        cliext::vector<Foo^> v2;
    
        v->push_back(s1);
        v2.push_back(s1);
    
        v->push_back(%s2);
        v2.push_back(%s2);
    
        // [Edit]
        // Geht doch, wird übersetzt, ist aber mehrdeutig, Intellisense zeigt Fehler an
        v[0]->bar = L"xx";
    
        // STL-Memberfunktion statt operator
        v->at(0)->bar = L"xxy";
    
        // Direkter Aufruf des Indexers, sieht komisch aus, geht aber
        v->default[0]->bar = L"qqa";
    
        // Der cliext::vector implementiert auch eine Liste
    
        IList<Foo^>^ list = v;
        list[0]->bar = L"abc";
    
        return 0;
    }
    

    Bleibt als Erkenntnis: C++/CLI taugt wirklich nur als minimaler Klebstoff zwischen C++ und C#. Sonst wird es zu kompliziert.



  • Bekomme da leider nur Fehler.
    Sehr strange.
    Kann das auch am Compiler liegen ?
    Hab Visual C++ Express.



  • v2[0]->bar = "test";
    Console::WriteLine (v2[0]->bar);

    Das wiederum geht.



  • pet0r-gnor schrieb:

    Kann das auch am Compiler liegen ?
    Hab Visual C++ Express.

    Welche Version denn ?

    Das Beispiel war mit VS2013 Pro getestet, nachträglich auch noch mit 2012.

    pet0r-gnor schrieb:

    v2[0]->bar = "test";
    Console::WriteLine (v2[0]->bar);

    Das wiederum geht.

    Das wird bei mir von beiden übersetzt, aber das v2[0] vom Intellisense rot unterstrichen. Nicht das erste Mal, das Compiler und Intellisense in C++/CLI ungleicher Meinung sind.



  • Meine Version ist Visual C++ 2008 Express SP1.
    Btw. vielen Dank.

    Du glaubst gar nicht wie sehr du mir geholfen hast.



  • Oh, bitte. Ich lerne ja auch was durch die Antworten. Mit diesen cliext Sachen habe ich nur höchst selten zu tun.

    Mit 2010 läuft das Beispiel übrigens auch. 2008 war die erste Visual Studio Version mit CLRSTL. Es könnte sein, dass sich seitdem wieder was geändert hat. Richtig dokumentiert ist das anscheinend nirgends.

    Du kannst dir auch das hier mal ansehen, das stammt aus 2008
    http://www.codeproject.com/Articles/24206/A-look-at-STL-CLR-performance-for-linear-container
    Die Ergebnisse dort legen auch nahe, möglichst viel in C# und nativem C++ zu machen und wenig in C++/CLI.

    Nachtrag:

    Das 2008er kann natürlich noch kein auto, da musst du statt

    auto s1 = gcnew Foo;
    

    den exakten Typ hinschreiben

    Foo^ s1 = gcnew Foo;
    

    (beim vector genauso)



  • Den push_back scheint er nicht so richtig zu wollen.

    #include "stdafx.h"
    #include <cliext/vector>
    
    using namespace System;
    using namespace System::Collections::Generic;
    
    ref struct Foo2
    {
    	String^ lang;
    	String^ value;
    };
    
    ref struct Foo
    {
        String^ id;
    	cliext::vector<Foo2^> v2;
    };
    
    int main(array<System::String ^> ^args)
    {
        Foo^ s1 = gcnew Foo;
    	Foo2^ s2 = gcnew Foo2;
        cliext::vector<Foo^> v1;
    
    	v1.push_back(s1);
        v1[0]->id = "00";
    
    	v1[0]->v2.push_back(s2);
    	v1[0]->v2[0]->lang = "00 - 00 - test";
    
    	v1[0]->v2.push_back(s2);
    	v1[0]->v2[1]->lang = "00 - 01 - test";
    
    	Console::WriteLine (v1[0]->id);
    	Console::WriteLine (v1[0]->v2[0]->lang);
    	Console::WriteLine (v1[0]->v2[1]->lang);
    
        return 0;
    }
    
    Ausgabe:
    00
    00 - 01 - test
    00 - 01 - test
    


  • pet0r-gnor schrieb:

    Den push_back scheint er nicht so richtig zu wollen.

    Doch, er pusht zweimal dieselbe Referenz, genauso wie du es geschrieben hast.



  • gnarz 😮
    Ich gehe jetzt irgendwohin wo es schön ist und erhänge mich.
    Vielen Dank Bashar.


Anmelden zum Antworten