Wpis z mikrobloga

#cpp #programowanie a bardziej #naukaprogramowania

C++. Mam klasę, w której jednym z elementów oraz jednym z parametrów konstruktora jest tablica, dajmy na to:

class Foo { public: double m_array [4] (...) };
Foo::Foo (int spam, double bar [], int n=4) { ... }//n to rozmiar tablicy
I teraz pytanie czy jest taka możliwość, żeby podczas tworzenia obiektu tej klasy zainicjalizować tą tablicę (bar, której wartości chcę potem przypisać do marray) konkretnymi wartościami bez tworzenia przed tym wywołaniem innej tablicy elementów double? Prawdopodobnie odpowiedź jest banalnie prosta, ale tworząc obiekt choćby w ten sposób

Foo bar = Foo(12, {1,2,3,4})
kompilator nie chce mi tego przetrawić (jedynie tak jak pisałem wyżej, tworząc wcześniej tablicę 4-el double i przekazując jej adres w miejscu {1,2,3,4} więc gdzieś musi być błąd
  • 23
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

via Android
  • 0
@ChestNoot: Dzięki, wcześniej nie znalazłem tego na stacku ale najwidoczniej słabo szukałem. Czyli jak widać da się, ale jedynie droga bardzo okrezna...
  • Odpowiedz
@lionbest: Tak, wiem, jednak chodziło mi tutaj głównie o zastosowanie standardowych tablic ;)
Dla uzupełnienia można dodać, że działa to także na tablicach typu std::vector, tyle że tam chyba wymagane jest, aby użytkownik przy inicjalizacji podał wszystkie wartości, które od niego wymagamy (tj. nie może podać 2 jeśli potrzebujemy 4, bo utworzy nam się tablica 2-elementowa zamiast tak jak w przypadku użycia array 4-elementowa, gdzie 2 będą miały wartości,
  • Odpowiedz
@lionbest: Hmmm... Właśnie nie bardzo rozumiem initializer_list, ale coś kombinuję. Próbuję skorzystać z initializer_list w przypadku gdy mam tablicę vector jako składową klasy i listę initializer_list daję jako parametr konstruktora (wraz z domyślnymi wartościami), ale wychodzi na to samo co gdyby parametrem konstruktora była tablica vector, bo gdy inicjalizuję obiekt liczbą argumentów mniejszą niż domyślna to lista, nie pozostawia mi tych pozostałych domyślnych wartości, a uwzględnia jedynie te,
  • Odpowiedz
@pingwindyktator: Nie ogarniam wszystkich elementów twojego kodu (głownie nullptr, o tym dopiero muszę poczytać), ale z tego co widzę tak na pierwszy rzut oka funkcja copy zdaje się być ... genialna! :D
Dzięki!
  • Odpowiedz
@lionbest: Kilka pewnie głupich z mojej strony pytań. Nie kumam, po co i na co używasz (void)spam; - normalnie do tej pory spotkałem się z takim zastosowaniem nawiasów ( np. (int) ) przy rzutowaniu na jakiś typ - rzutowanie na void yyy bezsens (który działa! :D)?. (chyba, że ma to jedynie pokazać, że da się stosować w konstruktorze więcej niż jeden paramet przy inicjalizacji i nic więcej?).
I druga rzecz,
  • Odpowiedz
@Calvert: Chodzi o usunięcie warninga. Jak nie używasz jakiegoś parametru to scastowanie na voida nie robi nic, ale kompilator nie powiadamia cię że nie użyłeś zmiennej.


Co do tej defaultowej wartości to o ile w konstruktorze z initializer_list będzie działać o tyle w tym pierwszym już nie bo ilość musi się zgadzać dokładnie, niby dało by się coś tam wymyślić na to ale nie będzie proste.
  • Odpowiedz
@lionbest: Ok, to ma bardzo sens :d

Ale jeżeli w domyślnym, pierwszym konstruktorze foo (int spam, T... values) : mArray{values...} w miejsce values... wstawię te same domyślne wartości tj. foo (int spam, T... values) : mArray{6,6,6,6} to wtedy wszystko śmiga tak jak powinno, więc chyba jest okej ( http://melpon.org/wandbox/permlink/oDwMCprZS1ADCC8i )

e:
Na marginesie przyznam jeszcze, że nie do końca rozumiem po co zastosowałeś tam w tym pierwszym konstruktorze : m_Array
  • Odpowiedz
@Calvert: Nie nie jest ok. Bo to nie działa ;-D więc spokojnie możesz wywalić values i mArray z listy inicjalizacyjnej.
Dlaczego to jest ważne? Bo nie da się inaczej znacjonalizować obiektu const foo, co jest w sumie ważną sprawą.
Przy czterech elementach nie ma to sensu, łatwiej jest napisać 4 osobne konstruktory, ale przy N wartościach to już będzie kłopotliwe.
  • Odpowiedz