const std::vector?



  • Hi,

    was wäre wohl die beste Möglichkeit ein konstantes Array von Objekten ohne Default-Konstruktor zu erstellen? C++0x mit

    const std::vector<Klasse> v = ({2, 3, 5, 7, 11}); // http://stackoverflow.com/questions/3701903/initialisation-of-static-vector
    

    steht nicht zur Verfügung. Boost für list_of() auch nicht. Wie gesagt, der Container ist mir egal, es könnte auch ein rohes Array sein.



  • my_class const array[] = { my_class(0), my_class(1), my_class(2) };
    
    // Falls gewünscht dann
    template<typename T, std::size_t N> std::size_t array_size(T(&)[N]) { return N; }
    std::vector<my_class> const vec(array, array + array_size(array));
    

    Einen Vektor direkt mit solchem Inhalt zu initialisieren ist in C++03 meines Wissens nicht möglich.



  • Warum steht boost::list_of nicht zur Verfügung? Ist ja Header-only das kannst du einfach kopieren. Ansonsten kann man eine billige Variante davon ja auch selbst schreiben:

    template<typename T>
    struct vector_of_helper {
      std::vector<T> v;
      vector_of_helper &operator()(T const &t) {
        v.push_back(t);
        return *this;
      }
      operator std::vector<T>() { return v; }
      vector_of_helper(T const &t) {
        v.push_back(t);
      }
    };
    
    template<typename T>
    vector_of_helper<T> vector_of(T const &t) {
      return vector_of_helper<T>(t);
    }
    
    // ...
    std::vector<int> const v = vector_of(1)(2)(3);
    


  • Äh, danke für die schnelle Antwort, aber ich habe irgendwie vergessen den Hauptpunkt meiner Frage zu stellen. oO
    Die erste Version oben wäre natürlich perfekt, nur soll das ein nicht-statischer Member einer Klasse werden und Folgendes geht leider nicht:

    struct test
    {
      test()
        : k({Klasse(5), Klasse(4)})
      {}
      const Klasse k[];
    };
    

    Sieht jemand einen besseren Ausweg als:

    struct test
    {
      test()
      {
        k.push_back(5);
        ..
      }
      std::vector<Klasse> k;
    };
    

    Perfekt wäre natürlich so was wie:

    struct test
    {
      const Klasse k[] = {Klasse(5), Klasse(4)};
    };
    

    Warum haben die Standardler das eigentlich verboten? Es ist doch eindeutig, was der Konstruktor hier machen muss.

    Ich sehe gerade: vector_of könnte eine Lösung sein..



  • Wenn der Arrayinhalt konstant ist, gibt es dann einen bestimmten Grund, dass er nicht statisch sein kann? Das sieht man eigentlich eher selten.



  • seldon schrieb:

    Wenn der Arrayinhalt konstant ist, gibt es dann einen bestimmten Grund, dass er nicht statisch sein kann? Das sieht man eigentlich eher selten.

    Hm.. vielleicht bin ich da auch gerade von etwas Falschem ausgegangen. Ist das Thread-safe? Ich weiß, der heilige Standard sagt da nichts zu, aber wie sieht es in der Praxis aus?

    void thread()
    {
      my_class c;
      c.do_smth_cool();
    }
    
    int main()
    {
      start_thread(thread);
      my_class c;
      c.do_smth_cool();
    }
    


  • Probleme mit Threads kannst du nur bekommen, wenn mindestens einer der Beteiligten schreiben will - bei reinen Lesezugriffen hast du dort keine Probleme.



  • threadersteller schrieb:

    seldon schrieb:

    Wenn der Arrayinhalt konstant ist, gibt es dann einen bestimmten Grund, dass er nicht statisch sein kann? Das sieht man eigentlich eher selten.

    Hm.. vielleicht bin ich da auch gerade von etwas Falschem ausgegangen. Ist das Thread-safe? Ich weiß, der heilige Standard sagt da nichts zu, aber wie sieht es in der Praxis aus?

    void thread()
    {
      my_class c;
      c.do_smth_cool();
    }
    
    int main()
    {
      start_thread(thread);
      my_class c;
      c.do_smth_cool();
    }
    

    Wenn my_class keine statischen Member hat, ist das typischerweise threadsafe. Sind ja zwei unterschiedliche Instanzen.
    Natürlich kannst du Probleme bekommen wenn do_smth_cool() (direkt oder indirekt) auf andere gemeinsam genutzte Daten zugreift, z.B. globale Variablen oder statische Member anderer Klassen.



  • Wie wäre es mit einer kleinen Streamklasse, die automatisch in einen std::vector umwandelbar ist?
    Man könnte natürlich (gibt's bei boost afaik auch) auch den Kommaoperator überladen (eine Taste weniger 😉 ).

    #include "VectorStream.hpp"
    
    class MyClass
    {
        int value;
        public:
        MyClass(int);
    };
    
    class Foo
    {
        std::vector<MyClass> bar;
        public:
        Foo() : bar(VectorStream<MyClass>() << 2 << 5 << 8 << 11 << 14 << 17 << 20) {}
    };
    

Log in to reply