Gå til innhold

Pipeline og templates


Anbefalte innlegg

Hei, jeg jobber på et skoleprosjekt hvor jeg er nødt til å lese inn, behandle og visualisere data. Jeg har valgt C++ som språk selvom jeg så godt som aldri har brukt det, pga. ytelsen og grafikkrammeverk som er tilgjengelig.

 

I denne typen oppgave har jeg funnet ut at en "pipeline" er passende. Men da trenger jeg en generisk og dynamisk en hvor man kan bytte ut komponenter under kjøring, alt etter på hvilken måte dataene skal visualiseres. Dette ser ikke ut til å være noe problem etter å ha lest flere artikler som denne. Når pipeline er slik kan vi enkelt utvide programmet, samt bytte ut elementer under veis i kjøringen.

 

Men jeg vil ha en pipeline som ikke krever at man har den samme typen data gjennom hele. For eksempel vil jeg kunne bruke dette som et interface:

 

class Processor {

public:

Processor(){}

virtual ~Processor(){}

virtual G process(T data){return G();}

};

 

og ha for eksempel en slik klasse som arver interfacet og spesifiserer det;

 

class ProcessorTest : public Processor<int, char> {

public:

ProcessorTest() : Processor<int, char>(){}

virtual ~ProcessorTest();

virtual char process( int data ) {

return 'a';

}

};

 

For til slutt å kunne lagre ProcessorTest i en tabell/liste/Vector med Processor og iterere over disse( element 1 må dermed ha samme utverdi G som element 2 sin innverdi T)

 

Men dette fungerer ikke, jeg er vant til Java og det hemmer muligens fantasien min i denne sammenhengen.

 

Et eksempel på hvordan jeg testet det:

 

ProcessorTest pt;

 

Processor *a = &pt;

 

//gir feilmelding

 

Jeg har lest at dette er fordi templates behandles under kompilering, og frykter derfor at en slik løsning ikke vil være mulig, eller er det? Er jeg tvunget til å lagre alle mulige data i en klasse og sende den gjennom hele pipeline? Eller kan jeg bruke en Singleton som alle elementene skriver til? Hvilke andre alternativer har jeg?

 

Enda i prosjektet er det faktisk aktuelt med en klasse som holder alle dataene som trengs, men med tanke på videre utvidelser så lurer jeg på om den kan bli stor og stygg tils slutt.

Lenke til kommentar
Videoannonse
Annonse

Men jeg vil ha en pipeline som ikke krever at man har den samme typen data gjennom hele.

 

Da er nok templates veien å gå.

 

Men dette fungerer ikke (...)

 

Hva betyr "fungerer ikke"?

 

Et eksempel på hvordan jeg testet det:

 

ProcessorTest pt;

Processor *a = &pt;

//gir feilmelding

 

Ja, selvsagt får du en feilmelding, men det er vanskelig å si hvilken, siden koden slik du skrev i starten av innlegget vil umulig kompilere. Hva med:

 

template<typename In, typename Out>
struct Base {
   Base(){}
   virtual ~Base(){}
   virtual Out process(const In& data){  return Out(); }
};

struct Derived : Base<std::string, int> {
   int process(const std::string &s){  return s.size(); }
};

int
main( int argc, char *argv[] ) 
{
   Derived d;
   Base<std::string, int> *b = &d;
   std::cout << b->process(std::string("sir mix-a-lot")) << "\n";
}

 

Hvilke andre alternativer har jeg?

 

Du kan la en subklasse arve fra en (spesialisert) template-klasse. Men vær klar over Base<T1, T2> peker vil ikke kunne peke på Base<T3, T4>-objekter (eller deres subklasser), når typene er forskjellige. Om det vil være problematisk for deg er litt vanskelig å si.

Lenke til kommentar

Takk for tilbakemelding:)

 

Det er nettopp dette jeg vil unngå:

Base<std::string, int> *b = &d;

 

Jeg drømmer om å skrive noe slikt(som jeg vet ikke er mulig, og det er dette jeg mener at ikke fungerer):

struct Derived : Base<std::string, int> {
   int process(const std::string &s){  return s.size(); }
};

struct DerivedTwo : Base<int, bool> {
   int process(const int &tall){  return tall > 0; }
};

int main() {
Derived d;
DerivedTwo dDos;

Vector<Base> vec;
vec.push_back(d);
vec.push_back(dDos);

}

 

Jeg lurer vel egentlig ikke på hvorfor jeg får noen feilmelding, men heller hvilke designalternativer jeg har.

 

Vet at void-pekere er brukt, men kan umulig se for meg at dette er god praksis?

 

Legger med kode med void* også så kanskja det kommer bedre fram hva problemet er:

class Processor {
   public: 
       void process(void *data) {}
};

class ProcessorTest : Processor {
   public:
       void process(void *data) { /*behandle data*/}
};

int main() {
   ProcessorTest p;
   Processor *a = &p;
   //har ikke kompilert men dette bør virke, og løse problemet mitt, men det er for stygt.
}

Endret av wannabe nerd
Lenke til kommentar

Jeg drømmer om å skrive noe slikt(som jeg vet ikke er mulig, og det er dette jeg mener at ikke fungerer):

 

Kort fortalt -- nei, det er ikke mulig. Heterogene containers finnes ikke i C++ (vel, utover å implementere alt selv fra bunn av basert på enumerations/void*).

 

Jeg lurer vel egentlig ikke på hvorfor jeg får noen feilmelding, men heller hvilke designalternativer jeg har.

 

Vet at void-pekere er brukt, men kan umulig se for meg at dette er god praksis?

 

Må man, så må man? Du kan jo la alle klassene dine arve fra Object :hrm:

Lenke til kommentar

Takk for hjelpen, etter masse styr med å lese om templates har jeg bestemt meg for å droppe det helt!

 

Jeg har bestemt meg for å ha et objekt som inneholder all data jeg trenger gjennom hele pipelinen, dette vil så bli brukt igjen for hver gjennomgang.

Minus: ikke like pent, dynamisk eller generelt.

Pluss: Enklere/Raskere å programmere for et stakkars javahode mtp feil og minnelekasjer, og programmet jobber mot samme minneloksajoner hele tiden.

 

Må man, så må man? Du kan jo la alle klassene dine arve fra Object :hrm:

 

Herp Java Derp ^-^

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...