Avatar
Kdosi
Neregistrovaný
Avatar
Kdosi:

Zdravím,
můj kód v šabloně T*:

List(T* source)
{
        count = jak?;
        printf("%i\n", count);
        list = (T*)malloc(count);

        *list = *source;
}

Vstupem je třeba pole string[3], přičemž string je "const char*". Když mám tedy 3 itemy, tak za jak dám ručně 96 a jede to jak má. Jenže já potřebuji řešení pro počet prvků n... sizeof vrací jak pro source, tak i pro *source 4.
Děkuji.

 
Odpovědět 13.10.2013 15:33
Avatar
vitamin
Člen
Avatar
Odpovídá na Kdosi
vitamin:
template <class T, size_t N> //N je pocet prvkov pola (velkost musi byt znma pri preklade)
void List(T (&source)[N]){
        //...
}
Editováno 13.10.2013 15:41
 
Nahoru Odpovědět 13.10.2013 15:40
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:

To je blbost. To tam rovnou dám parametr pro počet prvků a vynásobím jej pak 32... Jenže je to tedy pěkně naprd - chtěl jsem to jako deklaraci Listu s n prvky. Takhlen je už jednodušší volat Add, jelikož nejen, že neexistuje zkrácená verze initializace pole, ale jak v poli, tak v parametru budu muset dávat velikost pole...

 
Nahoru Odpovědět 13.10.2013 15:44
Avatar
vitamin
Člen
Avatar
Odpovídá na Kdosi
vitamin:

Co sa snazias naprogramovat?
Vies o tom ze malloc nevola constructory?

 
Nahoru Odpovědět 13.10.2013 15:48
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:
List<string> strings = *new List<string>(new string[3]{ ":((", ":D", "....." }, 3);

List třídu mám už dlouho, chtěl jsem jen zkrátit deklaraci, znám-li už nějaký počet prvků předem... Tohle to celé jen komplikuje - místo zjednodušení... :D

Jistě - jsem debil a dělám dynamické pole....

 
Nahoru Odpovědět 13.10.2013 15:51
Avatar
Kdosi
Neregistrovaný
Avatar
Kdosi:

Pročež doteď jsem v cyklu volal:

void Add(T item)
{
        count += 32;

        list = (T*)realloc(list, count);

        list[count / 32 - 1] = item;
}

Takhlen to nastavím rovnou - bez cyklu...

 
Nahoru Odpovědět 13.10.2013 15:57
Avatar
vitamin
Člen
Avatar
vitamin:
#include  <initializer_list>
template <class T>
class List{

        public:
                template<size_t N>
                List(const T (&source)[N]){
                        std::cout << "List sa inicializuje z pola o " << N << " prvkoch\n";
                }

                List(std::initializer_list<T>&& ilist){
                        std::cout << "List sa inicializuje z inicializer_listu o " << ilist.size() << " prvkoch\n";

                }
};


int main(){
        using namespace std;

        List<char> list1{"string"};
        List<char> list2{'a', 'b', 'c', 'd'};

        return 0;
}

Pouzivas strasne vela alokacii na heape, c++ nie je java ani c#...

Editováno 13.10.2013 16:00
 
Nahoru Odpovědět 13.10.2013 15:59
Avatar
Kdosi
Neregistrovaný
Avatar
Kdosi:

Já myslel, že to půjde s tím sizeof... Includovat se mi nechtělo. No nic - díky... Když už - C++ řeší kolize includů nějak lépe, než C? (Jako u Objective-C je import...)

 
Nahoru Odpovědět 13.10.2013 16:07
Avatar
vitamin
Člen
Avatar
Odpovídá na Kdosi
vitamin:

includy funguju rovnako ako v c, vecsina kompilatorov podporuje ale #pragma once alebo si spravys guary sam cez ifndef, define, endif.

Inak ta tvoja funkcia Add ma velku chybu, nevola sa konstruktor takze ti to v lepsom pripade bude padat alebo budu vznkat memory lake-y.

Editováno 13.10.2013 16:15
 
Nahoru Odpovědět 13.10.2013 16:14
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:

A pole/pointer z toho udělám jak? (Myslím tím T*...)

 
Nahoru Odpovědět 13.10.2013 17:46
Avatar
vitamin
Člen
Avatar
vitamin:
void* mem = malloc(sizeof(T));   //alokujes pamet

new(mem) T(...);   //zavolas konstruktor

reinterpret_cast<T*>(mem)->~T();     //zavolas destructor

free(mem);    //dealokujes pamet

Akonahle pouzivas malloc, realloc a free, tak si konstruktory a destruktory musis valoat rucne. Napr std::vector je podobne implementovany.

 
Nahoru Odpovědět 13.10.2013 18:41
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:

Ale já se ptal na to, co mám dělat s tím "std::initiali­zer_list"...

 
Nahoru Odpovědět 13.10.2013 18:51
Avatar
vitamin
Člen
Avatar
Odpovídá na Kdosi
vitamin:

Musis mat kompilator co podporuje c++11.
Musis includovat: <initializer_list>
A potom mozes pouzit ten priklad co som ti dal.

 
Nahoru Odpovědět 13.10.2013 18:54
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:

Nemůžu. Já používám T*. Ne list...

>g++ -W -Wall -Werror -std=gnu++11 -I ./ -o main.exe main.cpp
In file included from /usr/include/System.h:2:0,
                 from main.cpp:3:
/usr/include/System/Collections/Generic/List.h: In instantiation of ‘System::Collections::Generic::List<T>::List(std::initializer_list<_Tp>&&) [with T = const char*]’:
main.cpp:10:46:   required from here
/usr/include/System/Collections/Generic/List.h:39:6: error: invalid conversion from ‘std::initializer_list<const char*>::const_iterator {aka const char* const*}’ to ‘const char**’ [-fpermissive]
/usr/include/System/Collections/Generic/List.h:42:10: error:   initializing argument 1 of ‘void System::Collections::Generic::List<T>::Allocate(T*, int) [with T = const char*]’ [-fpermissive]
>Exit code: 1

Potřebuji z toho mít T*/[]...

 
Nahoru Odpovědět 13.10.2013 18:55
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:

Já nevím - připadám si, jako by jsi si myslel, že jsem úplně negramotný...

 
Nahoru Odpovědět 13.10.2013 18:57
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:

A cyklus jsem tam měl předtím - viz. hoře. Přijde mi zbytečné cyklit, když je to vše v požadovaném formátu - stačí T* nastavit na T*. Jediná věc byla, že jsem musel zadat jak do pole, tak do dalšího parametru velikost - je to ale lepší než cyklus zase...

 
Nahoru Odpovědět 13.10.2013 19:02
Avatar
Kit
Redaktor
Avatar
Odpovídá na Kdosi
Kit:

Nemůžu si pomoct, ale občas mi jako negramotný připadáš :)

Možná by nebylo špatné, kdyby ses konečně zaregistroval. Takhle mám tendenci si z tebe dělat srandu, i když vidím, že něco přece jen umíš.

Nahoru Odpovědět 13.10.2013 19:03
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
vitamin
Člen
Avatar
Odpovídá na Kdosi
vitamin:

Ak to spravne chapem tak sa snazis implementovat dynamicke pole na sposob std::vector. Aby si nas zmiatol tak si ho nasval List co sa pouziva vecsinou na zretaene zoznamy. Chces implementovat konstruktor v ktorom budes moct specifikovat zoznam prvkov ktore chces mat v poly po inicializacii. Chapem to spravne?

 
Nahoru Odpovědět 13.10.2013 19:07
Avatar
Kit
Redaktor
Avatar
Odpovídá na vitamin
Kit:

Seznam se dá implementovat nejen zřetězením elementů, ale i pomocí pole. Přitom pole je v běžných případech o dost rychlejší.

Nahoru Odpovědět 13.10.2013 19:13
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:

Tvl. Je to list jako vyšitý - stejný jako v C#. (Pak udělám i slovník - jako v C# - List.Add, List.Remove, List.RemoveAt, List.Count,...) Jen jsem doteď neměl v konstruktoru možnost zadat počáteční prvky. To jsem zařídil přes pole. Nevýhodou toho ale bylo, že se nedala dynamicky zjistit velikost - a když jsem se zde zeptal, začal jsi z toho dělat kdovíco...

List(T* source)
{
       count = jak?;
       list = (T*)malloc(count);

       *list = *source;
}

sizeof prostě nefunguje no. Tak já budu zadávat tu velikost ročně a smířím se s tím asi... :D

Negramotný fakt nejsem. A programuji už pár let - a to i komerčně... (Od strojáku po dotazovací jazyky + se dnes a denně hrabu v HW.)

 
Nahoru Odpovědět 13.10.2013 19:13
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kdosi
David Čápka:

Je zvláštní, že všechny tvé diskuze na všech fórech dopadají stejně.

Nahoru Odpovědět 13.10.2013 19:27
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:

Myslíš, jak v nich tvrdí, že není negramotný?

Nahoru Odpovědět 13.10.2013 19:29
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na David Čápka
Kdosi:

Přečti si první příspěvek. Kde jsem udělal chybu?

 
Nahoru Odpovědět 13.10.2013 19:30
Avatar
vitamin
Člen
Avatar
Odpovídá na Kdosi
vitamin:

To ze si predtym programoval v jave/c# ma hned napadlo po tom ako som zbadal toto: :D

List<string> strings = *new List<string>(new string[3]{ ":((", ":D", "....." }, 3);

To moje riesenie co som ti dal v na zaciatku pomocou referencie na staticke pole a incializer listu ta moholo naviest na spravne riesenie ale asi ti to moc nepomohlo. Budem taky velkoisi ze ti sem dam ukazkovy kod:

#include  <initializer_list>

template <class T>
class Vector{
                void* raw_data;
                T* data(size_t s = 0){return reinterpret_cast<T*>(raw_data) + s;}
                const T* data(size_t s = 0)const {return reinterpret_cast<const T*>(raw_data) + s;}

                size_t data_size = 0;
                size_t alloc_size = 0;

        public:
                Vector(size_t reserve = 0){
                        alloc_size = reserve +1;
                        raw_data = malloc(sizeof(T)*alloc_size);
                }

                ~Vector(){
                        clear();
                        free(raw_data);
                }

                size_t size()const{return data_size;}

                void clear(){
                        for(T* i = data(data_size-1); i >= data(); --i)
                                i->~T();

                        data_size = 0;
                }

                void Add(const T& x){           //prida prvok na koniec
                        if(data_size >= alloc_size){
                                alloc_size *= 2;
                                raw_data = realloc(raw_data, sizeof(T)*alloc_size);
                        }
                        new(data(data_size)) T(x);

                        ++data_size;
                }

                void Remove(){                  //odstrani prvok z konca
                        if(data_size){
                                data(--data_size)->~T();
                        }
                }

                Vector(std::initializer_list<T>&& ilist):Vector(ilist.size()){
                        for(const T& x: ilist)
                                Add(x);
                }

                T* begin(){return data();}
                const T* begin()const{return data();}
                T* end(){return data(data_size);}
                const T* end()const{return data(data_size);}
};

#include <iostream>
#include <string>

int main(){
        using namespace std;

        Vector<string> vec{"string1", "string2", "string3"};
        vec.Add("string4");
        vec.Add("string5");
        vec.Add("string6");
        vec.Remove();
        vec.Add("string7");

        for(auto& str : vec)cout << str << '\n';

        return 0;
}
Editováno 13.10.2013 19:45
 
Nahoru Odpovědět 13.10.2013 19:45
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 24 zpráv z 24.