Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Erben von parametrischen Klassen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
05.04.2016, 21:48 Uhr
Tetje



Hallo,

für ein kleines privates Projekt wollte ich die Klasse Pair<type_a, type_b> und gleich noch als Triple<type_x, type_y, type_z> implementieren. Warum das, ich brauche das für ein kleines Projekt für ein Mikrokontroller und dahierfür die STL nicht implemiert ist, wollte/musste ich es selbst machen. Als kleines Extra wollte ich für diese Klasse die boolschen Operatoren überladen, damit ich Pair mit Pair, Pair mit Triple etc. einfach vergleichen kann.
Im folgenden lasse ich die Typenbezeichnungen raus und schreibe <> statt der oben angebgenen Bezeichner.
Da es hier um Verebung und Template auf einmal geht, scheint es mir doch recht speziel und kompliziert. Ich habe den ganzen vereinfachten Code unten gepostet, falls jemand Probeweise komplieren möchte. Ich würde mich dennoch über freundliche Hilfe freuen. Die Beschreibung ist leider schon sehr lang geworden.

Ich bin noch etwas neu in C++ ich lerne quasi mit diesem Projekt mit. Ich hatte erst beide Klassen einzeln implementiert hatte. Nun dachte ich mir aber, wenn ich mir von Triple<> von Pair<> erbt, bekomme ich dann nicht den vergleich zwischen Triple und Pair und Pair und Triple aufgrund der Polymorphie geschenkt? Oder irre ich hierbei, wenn ich davon ausgehe immer wenn nun das Triple mit einem Pair verglichen wird, es impliziert selbst in ein Pair umgewandelt wird?
Stimmt das so? Muss ich hierfür was tun?

Nun wollte ich den neu geschrieben Code testen. Leider komme ich hierbei immerzu der Fehlermeldung, die ich im folgenden beschreibe. Zur Vereinfach habe ich erstmal einen Header für das eine Beispielklasse Number<in_Type> geschrieben. Wenn Pair<> von Number<> erbt, ist es ja so ähnlich wie wenn Triple<> von Pair<> erbt.


C++:
#ifndef Number_h
#define Number_h


template<typename inType=int>
class Number {
    public:
        Number();
        Number(inType f);
        
        bool operator<(const Number<inType>& secNumber);
        bool operator==(const Number<inType>& secNumber);

        bool operator!=(const Number<inType>& secNumber);
        bool operator<=(const Number<inType>& secNumber);
        bool operator>(const Number<inType>& secNumber);
        bool operator>=(const Number<inType>& secNumber);

        inType getFrist();
    protected:
        inType first;

};
#include "Number.cpp"    //musst be included because
                        //we're using templates

#endif // !Number_h



Von dieser Klasse erbt, nun Pair<>:

C++:
#ifndef Pair_H
#define Pair_H

template<typename type_a = int,typename type_b = int>
class Pair : public  Number<type_a>{

    public:

        Pair();
        Pair(type_a f, type_b s);

        inline type_b getSecond()const;

        bool operator<(const Pair< type_a, type_b>& secondPair);
        bool operator==(const Pair< type_a, type_b>& secondPair);

        bool operator!=(const Pair< type_a, type_b>& secondPair);
        bool operator<=(const Pair< type_a, type_b>& secondPair);
        bool operator>(const Pair< type_a, type_b>& secondPair);
        bool operator>=(const Pair< type_a, type_b>& secondPair);

    protected:    
        const type_b second;

#include "Pair.cpp" //musst be included because
                    //we're using templates

#endif




Visual Studio 15 wirft nun folgende drei Fehlermeldungen:

Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
Fehler C2039 "getFirst": Ist kein Element von "Pair<int,int>" Pair_Triple pair.cpp 39
Fehler C2039 "getFirst": Ist kein Element von "Pair<int,int>" pair.cpp 28
Fehler C2143 Syntaxfehler: Es fehlt "," vor "<" Pair_Triple \pair.h 7


Wobei ich davon ausgehe, dass der Wesentliche Fehler der Letzte ist.

Die beiden oberen Fehler werden von Mircosoft so erklärt:

https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=DE-DE&k=k%28C2039%29&rd=true

Der untere wie folgt:
https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=DE-DE&k=k%28C2143%29&rd=true

Ich verstehe das so als, ob nun der Compiler als die < als kleiner Zeichen versteht, statt mit Templaten in Verbindung zu bringen. Leider ist, dies nun klein Problem das in Büchern behandelt wird, und so versuchte ich mich auf die Internetsuche zum einem auf der Suche mit der Fehlermeldung zum Anderem Paschalsiert im Sinne inherence from template class etc. Viel ergab sich dabei nicht und es half auch nicht weiter.

Nun habe ich desweiteren CodeBlocks geöffnet und das Projekt mit dem g++ Kompiler versucht zu übersetzen. Da mir das ab und an schon geholfen hat, eine andere Fehlermeldung zu lesen. Als Schalter sind -Wall -Wextra und -std=c++11 aktiviert. Dabei wurden noch kleinere Fehler in der Pair.cpp entdeckt, die ich korriert habe, danach erscheinen nur noch Fehler die auch den ersten beiden Fehlermeldungen Warnungen, die den ersten beiden von Visual Studio ähneln. Wie:


Zitat:

In member function 'bool Pair<type_a, type_b>::operator<(const Pair<type_a, type_b>&)':|
error: 'first' was not declared in this scope|
In instantiation of 'bool Pair<type_a, type_b>::operator==(const Pair<type_a, type_b>&) [with type_a = int; type_b = int]':|
required from here|
error: 'const class Pair<>' has no member named 'getFirst'|
In instantiation of 'bool Pair<type_a, type_b>::operator<(const Pair<type_a, type_b>&) [with type_a = int; type_b = int]':|
required from here|
error: 'const class Pair<>' has no member named 'getFirst'|
In member function 'bool Pair<type_a, type_b>::operator==(const Pair<type_a, type_b>&) [with type_a = int; type_b = int]':|
warning: control reaches end of non-void function [-Wreturn-type]|
In member function 'bool Pair<type_a, type_b>::operator<(const Pair<type_a, type_b>&) [with type_a = int; type_b = int]':|
warning: control reaches end of non-void function [-Wreturn-type]|



Aber diese Fehler sollten ja eigentlich nicht auftreten, wenn Pair<> von Number<> erbt, oder?

Ich habe nun folgende Fragen zu dem Problem:
1: Ist das Problem überhaupt mittels vererbung zu lösen? Die Erwartung das durch Polymorphismus auch die Vergleiche zwischen Pair und Triple automatisch funktioniert, indem Triple implizit in Pair umgewandelt wird, stimmt diese so?
2: Muss ich was beachten, damit diese stimmt?
3: Wie muss ich die Klassen anpassen, damit diese sich so verhalten wie ich es eben beschrieben habe?

Vielen Dank und freundlichen Grüße,

Tetje

Dieser Post wurde am 05.04.2016 um 21:51 Uhr von Tetje editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
05.04.2016, 22:39 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hi,

kann es sein das dein Problem einfach nur ein schreibfehler ist?


C++:
inType getFrist();



da steht frist nicht first ?
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
06.04.2016, 13:12 Uhr
ao

(Operator)



Zitat von Tetje:
1: Ist das Problem überhaupt mittels vererbung zu lösen? Die Erwartung das durch Polymorphismus auch die Vergleiche zwischen Pair und Triple automatisch funktioniert, indem Triple implizit in Pair umgewandelt wird, stimmt diese so?

Die Frage ist, ob es sinnvoll ist, das so zu machen. Nicht alles, was syntaktisch möglich ist, ist auch sinnvoll.

Mit der Vererbung drückst du eine Beziehung zwischen den Klassen aus, und zwar: Ein Triple IST ein Pair, das heißt, es hat ALLE Eigenschaften eines Pair (und evtl. noch eigene darüberhinaus). Ist das so? Wenn nicht, ist es vermutlich besser, die getrennten Definitionen zu behalten.

Oder dient die Vererbung nur dazu, Code wiederzuverwenden? Das wäre (nach modernerer Auffassung) kein hinreichender Grund für eine Vererbungsbeziehung.

Und noch eine Grundsatzfrage: Wozu braucht man Tupel eigentlich? Was können die, was über ein struct (oder eine class mit entsprechenden Properties) hinausgeht?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
07.04.2016, 21:12 Uhr
Tetje



Ich habe gestern noch den Code etwas verändert, was die Anzahl der Fehlermeldungen zumindest reduziert hat.
Aber erstmal zu aos (rethorischen) Fragen.

Zur ersten Fragen eigentlich ja, so wie ich es verwenden will.

Zu zweitens, es bietet mir durch die Templates den Code mit nur wenigen Änderungen wiederverwerten und so mit wenigen Änderungen optimal anzupassen. Zum Beispiel: Pair<unsigned char, unsigned char> wenn ich Mal weniger Platz brauche und es vllt. mal besonders schnell gehen muss, oder wenn ich die Genauigkeit und die Größe des Datenbereichs brauche Pair<double, double> und das war es auch schon...

Nun zum Veränderten Code, habe nun first auch first geschrieben, getFirst auch und constant gesetzt, wegen einer Typenumwandlung und dann auch gleich first const gesetzt.


C++:
#ifndef Number_h
#define Number_h


template<typename inType=int>
class Number {
    public:
        Number();
        Number(inType f);

        bool operator<(const Number<inType>& secNumber);
        bool operator==(const Number<inType>& secNumber);

        bool operator!=(const Number<inType>& secNumber);
        bool operator<=(const Number<inType>& secNumber);
        bool operator>(const Number<inType>& secNumber);
        bool operator>=(const Number<inType>& secNumber);

        inType getFirst() const;
    protected:
        const inType first;

};
#include "Number.cpp"    //musst be included because
                        //we're using templates

#endif // !Number_h



In Pair habe ich, glaube ich, nichts geändert:

C++:
#ifndef Pair_H
#define Pair_H

template<typename type_a = int,typename type_b = int>
class Pair : public  Number<type_a>{

    public:

        Pair();
        Pair(type_a f, type_b s);

        //inline type_a getFirst() const;
        inline type_b getSecond()const;

        bool operator<(const Pair< type_a, type_b>& secondPair);
        bool operator==(const Pair< type_a, type_b>& secondPair);

        bool operator!=(const Pair< type_a, type_b>& secondPair);
        bool operator<=(const Pair< type_a, type_b>& secondPair);
        bool operator>(const Pair< type_a, type_b>& secondPair);
        bool operator>=(const Pair< type_a, type_b>& secondPair);

    protected:     //const type_a first;
                const type_b second;
};

#include "Pair.cpp" //musst be included because
                    //we're using templates


Visual studio wirft nur noch:

Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
Fehler C2143 Syntaxfehler: Es fehlt "," vor "<" Pair_Triple \pair\pair.h 7

Die Fehler die der g++ wirft sind gänzlich anders und beziehen sich die Implementierungen der Klassen, was ich aus Platzgründen im nächsten Post beschreiben möchte.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
07.04.2016, 21:29 Uhr
Tetje



Zu nun gleich die Number.cpp


C++:
#include "Number.h"

#ifndef Number_CPP
#define Number_CPP

//constructors:
template<typename inType>
Number<inType>::Number(inType f) : first(f) {}


template<typename inType>
Number<inType>::Number() : first(static_cast<inType>(0)) {}


//getter
template<typename inType>
inline inType Number<inType>::getFirst() const { return first; }


//operators:
template<typename inType>
bool Number<inType>::operator< (const Number<inType>& secNumber) {
    return first < secNumber.first;
};



template<typename inType>
bool Number<inType>::operator== (const Number<inType>& secNumber) {
    return first == secNumber.first;
};


template<typename inType>
bool Number<inType>::operator!=(const Number<inType>& secNumber) { return !(*this == secNumber); };

template<typename inType>
bool Number<inType>::operator<=(const Number<inType>& secNumber) { return ((*this < secNumber) || (*this == secNumber)); };

template<typename inType>
bool Number<inType>::operator>(const Number<inType>& secNumber) { return !(*this <= secNumber); };

template<typename inType>
bool Number<inType>::operator>=(const Number<inType>& secNumber) { return !(*this < secNumber); };

#endif




und die Pair.cpp:


C++:
#include "Pair.h"

#ifndef Pair_CPP
#define Pair_CPP

template <typename type_a, typename type_b>
Pair<type_a, type_b>::Pair() : Number<type_a>::Number(), second(static_cast<type_b>(0)) {};

template <typename type_a, typename type_b>
Pair<type_a, type_b>::Pair(type_a f, type_b s) : Number<type_a>(f), second(s) {};


template <typename type_a, typename type_b>
inline type_b Pair<type_a, type_b>::getSecond() const {
    return second;
}


template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator==(const Pair< type_a, type_b>& secondPair) {
    return ((first == secondPair.getFirst()) && (getSecond() == secondPair.getSecond()));
}

template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator!=(const Pair< type_a, type_b>& secondPair) {
    return     (!(*this == secondPair));
}


template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator<(const Pair< type_a, type_b>& secondPair) {
    return ((first <= secondPair.getFirst()) && (getSecond() < secondPair.getSecond()));
}


template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator<=(const Pair< type_a, type_b>& secondPair) {
    return ((*this < secondPair) || (*this == secondPair));
}


template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator>(const Pair< type_a, type_b>& secondPair) {
    return     (!(*this <= secondPair));
}

template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator>=(const Pair< type_a, type_b>& secondPair) {
    return     (!(*this < secondPair));
}

#endif



Der Testtreiber sieht wie folgt aus:

C++:

#include <iostream>
#include <iomanip>

using namespace std;

int main() {
    Number<> num1{ 1 };

    Pair<> pair1{ 1, 1 };
    Pair<> pair2{ 1, 2 };

    cout << "num1 == pair1" << setw(10) << (num1 == pair1) << endl;
    cout << "num1 < pair1" << setw(10) << (num1 < pair1) << endl;
    cout << "num1 > pair1" << setw(10) << (num1 > pair1) << endl;


    cout << "pair1 == pair2" << setw(10) << (pair1 == pair2) << endl;
    cout << "pair2 < pair2" << setw(10) << (pair1 < pair2) << endl;
    cout << "pair2 > pair2" << setw(10) << (pair1 > pair2) << endl;

}



g++ wirft dabei zwei Fehler und zwei Wahrungen:


Zitat:

||=== Build: Debug Win32 in Pair_Triple (compiler: GNU GCC Compiler) ===|
Pair.cpp||In member function 'bool Pair<type_a, type_b>::operator==(const Pair<type_a, type_b>&)':|
Pair.cpp|28|error: 'first' was not declared in this scope|
Pair.cpp||In member function 'bool Pair<type_a, type_b>::operator<(const Pair<type_a, type_b>&)':|
Pair.cpp|39|error: 'first' was not declared in this scope|
Pair.cpp||In member function 'bool Pair<type_a, type_b>::operator==(const Pair<type_a, type_b>&) [with type_a = int; type_b = int]':|
Pair.cpp|29|warning: control reaches end of non-void function [-Wreturn-type]|
Pair.cpp||In member function 'bool Pair<type_a, type_b>::operator<(const Pair<type_a, type_b>&) [with type_a = int; type_b = int]':|
Pair.cpp|40|warning: control reaches end of non-void function [-Wreturn-type]|
||=== Build failed: 2 error(s), 2 warning(s) (0 minute(s), 2 second(s)) ===|


Zum einen: wisst ihr warum first nicht deklariert sein soll? Immerhin ist es doch ein Atrribut des Supertyps. Zum Anderen: wisst ihr, wie man das Problem mit der richtigen Initialisierung des Subtyps Pair löst?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
08.04.2016, 10:42 Uhr
ao

(Operator)



Zitat von Tetje:
Ich habe gestern noch den Code etwas verändert, was die Anzahl der Fehlermeldungen zumindest reduziert hat.
Aber erstmal zu aos (rethorischen) Fragen.

Tetje, meine Fragen sind nicht rhetorisch, sondern ernst gemeint. Es sind schon viele Scheiß-Designs dadurch entstanden, dass man auf Teufel komm raus versucht hat, Vererbungsbeziehungen zu definieren, wo eigentlich gar keine bestehen.

"Vererbung" heißt im OO-Sinn nicht, Code zu vererben, sondern Eigenschaften. Ich halte den Begriff auch nicht für besonders glücklich gewählt.

Nicht ohne Grund erlauben modernere OO-Sprachen (C#, Java) im Gegensatz zu C++ keine Mehrfachableitungen. Dadurch, dass es nur eine Ableitungslinie ohne Verzweigungen geben kann, wird der Entwickler dazu gebracht, sich über sein Design Gedanken zu machen und nicht kreuz und quer abzuleiten, nur weil es geht.


Zitat:
Zur ersten Fragen eigentlich ja, so wie ich es verwenden will.

Es geht nicht um "verwenden wollen". Es geht um die Wahl der richtigen Klassenbeziehung. Ein Triple ist kein Pair, darum kann Pair keine Basisklasse für Triple sein. Wenn du anderer Ansicht bist, dann begründe das.


Zitat:
Zu zweitens, es bietet mir durch die Templates den Code mit nur wenigen Änderungen wiederverwerten und so mit wenigen Änderungen optimal anzupassen.

Ich stelle nicht in Frage, dass es sich um Templates handelt. Das sehe ich ein und halte ich für richtig. Ich stelle die Ableitung "class Pair : public Number" in Frage.

Im Übrigen scheinst du gerade etwas durcheinander zu sein mit deinen beiden Projekten (Pair/Number und Triple/Pair), du postest nämlich offenbar den Code aus dem einen Projekt und die Fehlermeldung aus dem andern:

Zitat:
Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
Fehler C2143 Syntaxfehler: Es fehlt "," vor "<" Pair_Triple \pair\pair.h 7

Lass uns doch einfach an einem Projekt arbeiten, und ruhig an dem vermeintlich komplizierteren. So schlau wie du sind wir bestimmt auch.

Es könnte sein, dass dieser Syntaxfehler die Ursache allen Übels ist. Ein funktionierendes Trivialbeispiel ist hier (ungeachtet der Tatsache, dass ich Triple : public Pair für falsch halte):

C++:
template <typename T1, typename T2> class Pair
{
protected:
    T1 a;
    T2 b;
    
public:

    Pair (T1 a_, T2 b_) : a (a_), b (b_) {}
    
    T1 GetA () const { return a; }
    T2 GetB () const { return b; }    
};


template <typename T1, typename T2, typename T3> class Triple
: public Pair<T1, T2>
{
    T3 c;
    
public:
    Triple (T1 a_, T2 b_, T3 c_)
        : Pair<T1, T2> (a_, b_)
        , c (c_)
        {}
        
    T3 GetC () const { return c; }    
};

#include <iostream>

int main ()
{
    Pair<int, int> p (1, 2);
    std::cout
        << p.GetA () << " "
        << p.GetB () << std::endl
        ;

    Triple <int, int, int> t (1, 2, 3);
    std::cout
        << t.GetA () << " "
        << t.GetB () << " "
        << t.GetC () << std::endl
        ;
}


Dieser Post wurde am 08.04.2016 um 10:46 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
08.04.2016, 10:56 Uhr
ao

(Operator)


Und hier ist nochmal Triple mit einer funktionierenden Operator-Überladung:

C++:
template <typename T1, typename T2, typename T3> class Triple
: public Pair<T1, T2>
{
    T3 c;
    
public:
    Triple (T1 a_, T2 b_, T3 c_)
        : Pair<T1, T2> (a_, b_)
        , c (c_)
        {}
        
    T3 GetC () const { return c; }    
    
    bool operator==(const Triple<T1, T2, T3> & other) const
    {
        return (Pair<T1,T2>::GetA() == other.GetA()
            && Pair<T1,T2>::GetB() == other.GetB()
            && GetC() == other.GetC()
            );
    }
};


Die Basisklasse ist nicht einfach Pair, sondern Pair<T1, T2>. Offenbar muss man das explizit angeben. Kennt jemand den Grund dafür?

Dieser Post wurde am 08.04.2016 um 11:02 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
08.04.2016, 12:40 Uhr
ao

(Operator)


Nachdem ich mal ein bisschen über die Klasse std::tuple gelesen habe (die ja wohl irgendwie das Vorbild für all das hier ist), frage ich mich immer mehr, wozu diese Tupel eigentlich gut sein sollen. Ein generischer Sack von Werten, in dem buchstäblich alles mögliche drinstecken kann - was soll das? Was fängt man in realen Anwendungen (die mehr machen als make_tuple und std::cout << std::get<0>(mytuple)) damit an? Ich wäre dankbar für Beispiele.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
09.04.2016, 12:34 Uhr
Tetje



Hallo,

ist schon sehr blöde ich habe sehr drauß geachtet und bin meinen Code mehrfach durchgegangen und habe ihn mit deinem Verglichen, und das mehrfach aber es ändert nichts am Problem.

Naja zur Frage, ob man Trible sinnvoll von Pair eben lassen kann. Worin unterscheiden sich den Triple und Pair, was ist denn fundamental anders? Hat denn Pair Eigenschaften die Triple nicht hat?
Das sind nun die Frage, die ich mir stelle und für mich siehts nun so aus... Pair hat alle Eigenschaften die auch Triple hat... im Sinne der Informatik die selben Attribute und überladen auch die selben Operatoren... Was ist der Unterschied, nun Pair hat zwei Attribute und Triple drei, sollange ich gewähre(n kann), dass die ersten zwei Attribute vom selben Typ sind wie die beiden Attibute von Pair, dann kommen mit der Vererbung nur noch das eine Attribut drauß und die Möglichkeit mit anderen Triples zu vergleichen... Wobei man auch hier eingentlich sicherstellen müsste, das deren Typen gleich sind, oder zumindest ähnlich...
Für mich klingt das also schon sehr nach einem sinnvollem Beispiel für Vererbung, oder was spricht aus deiner Sicht dagegen?
Ich zitiere noch Mal den Code diesmal mit Triple<> und Pair<> und die Fehlermeldungen... die ich von den beiden Kompilern erhalte. Ich habe es mehrfach neben deinen Bespielcode gelegt und keinen wirklichen Unterschied gefunden.

Pair.h:

C++:
#ifndef Pair_H
#define Pair_H

template<typename type_a = int, typename type_b = int>
class Pair {

public:

    Pair();
    Pair(type_a f, type_b s);

    inline type_a getFirst() const;
    inline type_b getSecond()const;

    bool operator<(const Pair< type_a, type_b>& secondPair);
    bool operator==(const Pair< type_a, type_b>& secondPair);

    bool operator!=(const Pair< type_a, type_b>& secondPair);
    bool operator<=(const Pair< type_a, type_b>& secondPair);
    bool operator>(const Pair< type_a, type_b>& secondPair);
    bool operator>=(const Pair< type_a, type_b>& secondPair);

protected:    
    const type_a first;
    const type_b second;
};

#include "Pair.cpp" //musst be included because
//we're using templates

#endif



Triple.h

C++:
#ifndef Triple_H
#define Triple_H

//does absoluteley not solve the problem...
//template<typename type_x = int, typename type_y = int> Pair<type_x, type_y>;

template<typename type_x = int, typename type_y = int, typename type_z = int>
class Triple : public Pair<type_x, type_y> {
public:
    Triple();
    inline Triple(type_x f, type_y s, type_y t);

    type_z getThird() const;

    bool operator ==(const Triple<type_x, type_y, type_z>& secondTriple);
    bool operator!=(const Triple<type_x, type_y, type_z>& secondTriple);
    bool operator<(const Triple<type_x, type_y, type_z>& secondTriple);
    bool operator<=(const Triple<type_x, type_y, type_z>& secondTriple);
    bool operator>(const Triple<type_x, type_y, type_z>& secondTriple);
    bool operator>=(const Triple<type_x, type_y, type_z>& secondTriple);

private:
    const type_z third;
};

#include "Triple.cpp" //musst be included because
//we're using templates

#endif



pair.cpp

C++:
#include "Pair.h"

#ifndef Pair_CPP
#define Pair_CPP

//ctor
template <typename type_a, typename type_b>
Pair<type_a, type_b>::Pair() : first(static_cast<type_b>(0)), second(static_cast<type_b>(0)) {};

template <typename type_a, typename type_b>
Pair<type_a, type_b>::Pair(type_a f, type_b s) : first(f), second(s) {};


//getter
template <typename type_a, typename type_b>
inline type_a Pair<type_a, type_b>::getFirst() const {
    return first;
}

template <typename type_a, typename type_b>
inline type_b Pair<type_a, type_b>::getSecond() const {
    return second;
}

//basic comperator
template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator==(const Pair< type_a, type_b>& secondPair) {
    return ((first == secondPair.getFirst()) && (getSecond() == secondPair.getSecond()));
}

template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator<(const Pair< type_a, type_b>& secondPair) {
    return ((first <= secondPair.getFirst()) && (getSecond() < secondPair.getSecond()));
}

//derived comperators
template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator!=(const Pair< type_a, type_b>& secondPair) {
    return     (!(*this == secondPair));
}

template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator<=(const Pair< type_a, type_b>& secondPair) {
    return ((*this < secondPair) || (*this == secondPair));
}

template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator>(const Pair< type_a, type_b>& secondPair) {
    return     (!(*this <= secondPair));
}

template <typename type_a, typename type_b>
bool Pair<type_a, type_b>::operator>=(const Pair< type_a, type_b>& secondPair) {
    return     (!(*this < secondPair));
}

#endif


Dieser Post wurde am 09.04.2016 um 12:36 Uhr von Tetje editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
09.04.2016, 12:35 Uhr
Tetje



Triple.cpp:

C++:
#include "Triple.h"

#ifndef Triple_CPP

#define Triple_CPP

//ctor
template<typename type_x, typename type_y, typename type_z>
Triple<type_x, type_y, type_z>::Triple() : Pair<type_x, type_y>(), third(t) {};

template<typename type_x, typename type_y, typename type_z>
Triple<type_x, type_y, type_z>::Triple(type_x f, type_y s, type_y t) : Pair<type_x, type_y>(f, s), third(static_cast<type_z>(0)) {};

//getter
template<typename type_x, typename type_y, typename type_z>
type_z Triple<type_x, type_y, type_z>::getThird() const {
    return third;
}

//basic comparator
template<typename type_x, typename type_y, typename type_z>
bool Triple<type_x, type_y, type_z>::operator ==(const Triple<type_x, type_y, type_z>& secondTriple) {
    return ((getFirst() == secondTriple.getFirst()) &&
        (getSecond() == secondTriple.getSecond()) &&
        (getThird() == secondTriple.getThird()));
}

template<typename type_x, typename type_y, typename type_z>
bool Triple<type_x, type_y, type_z>::operator<(const Triple<type_x, type_y, type_z>& secondTriple)
{
    return ((getFirst() <= secondTriple.getFirst()) &&
        (getSecond() <= secondTriple.getSecond()) &&
        (getThird() < secondTriple.getThird()));
}


//derived comparators
template<typename type_x, typename type_y, typename type_z>
bool Triple<type_x, type_y, type_z>::operator !=(const Triple<type_x, type_y, type_z>& secondTriple) {
    return (!(*this == secondTriple));
}

template<typename type_x, typename type_y, typename type_z>
bool Triple<type_x, type_y, type_z>::operator <=(const Triple<type_x, type_y, type_z>& secondTriple) {
    return ((*this < secondTriple) || (*this == secondTriple));
}

template<typename type_x, typename type_y, typename type_z>
bool Triple<type_x, type_y, type_z>::operator >(const Triple<type_x, type_y, type_z>& secondTriple) {
    return (!(*this <= secondTriple));
}

template<typename type_x, typename type_y, typename type_z>
bool Triple<type_x, type_y, type_z>::operator >=(const Triple<type_x, type_y, type_z>& secondTriple) {
    return (!(*this < secondTriple));
}

#endif



Testtreiber:

C++:
#include "Pair.h"
#include ".\..\Triple\Triple.h"

#include <iostream>
#include <iomanip>

using namespace std;

int main() {

    Pair<> pair1{ 1, 1 };
    Pair<> pair2{ 1, 2 };

    Triple<> triple1{ 1, 1, 1 };
    Triple<> triple2{1, 1, 2};


    cout << "pair1 == pair2" << setw(10) << (pair1 == pair2) << endl;
    cout << "pair2 < pair2" << setw(10) << (pair1 < pair2) << endl;
    cout << "pair2 > pair2" << setw(10) << (pair1 > pair2) << endl;


    cout << "pair1 == triple1" << setw(10) << (pair1 == triple1) << endl;
    cout << "pair1 == triple2" << setw(10) << (pair1 == triple2) << endl;

    cout << "triple1 == triple2" << setw(10) << (triple1 == triple2) << endl;
    cout << "triple1 < triple2" << setw(10) << (triple1 < triple2) << endl;
    cout << "triple1 > triple2" << setw(10) << (triple1 > triple2) << endl;

}



So man sehen Visual Studio wirft die selbe Fehlermeldung wie immer:


Zitat:

Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
Fehler C2143 Syntaxfehler: Es fehlt "," vor "<" ..\triple\triple.h 8



Die Fehlermeldung des g++ sieht sehr ähnlich aus:

Zitat:

||=== Build: Debug Win32 in Pair_Triple (compiler: GNU GCC Compiler) ===|
.\..\Triple.h|8|error: expected template-name before '<' token|
.\..\Triple.h|8|error: expected '{' before '<' token|
.\..\Triple.h|8|error: expected unqualified-id before '<' token|
.\..\Triple.cpp|9|error: invalid use of incomplete type 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.h|8|error: declaration of 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.cpp|12|error: invalid use of incomplete type 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.h|8|error: declaration of 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.cpp|16|error: invalid use of incomplete type 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.h|8|error: declaration of 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.cpp|22|error: invalid use of incomplete type 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.h|8|error: declaration of 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.cpp|29|error: invalid use of incomplete type 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.h|8|error: declaration of 'class Triple<type_x, type_y, type_z>'|
.\..\riple.cpp|39|error: invalid use of incomplete type 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.h|8|error: declaration of 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.cpp|44|error: invalid use of incomplete type 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.h|8|error: declaration of 'class Triple<type_x, type_y, type_z>'|
.\..\riple.cpp|49|error: invalid use of incomplete type 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.h|8|error: declaration of 'class Triple<type_x, type_y, type_z>'|
C:\Users\Sebastian\Documents\Programmierung\C++ - Arduino\Triple\Triple.cpp|54|error: invalid use of incomplete type 'class Triple<type_x, type_y, type_z>'|
.\..\Triple.h|8|error: declaration of 'class Triple<type_x, type_y, type_z>'|
||=== Build failed: 21 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|



Das sind ganze 21 Fehler, aber die meisten Hängen wohl vom den ersten Paar Fehlermeldungen ab, die ähnlich auschauen, wie der von visual Studio...

https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=DE-DE&k=k%28C2143%29&rd=true

Aber was mir davon helfen soll, weiß ich nicht, habe die gesamte Seite durchgearbeitet und ich weiß nicht, wie mir das weiter hilft. Habe mal einfach ein paar Sachen ausprobiert und es wurde eher schlimmer...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: