Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Operatoren überladen

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 <
010
09.11.2004, 15:55 Uhr
Tommix




C++:
class test
{
    int i;

public:
    test(int i_): i(i_) {}
    operator int() {return i;}

    friend test operator+(test a, test b);
};

test operator+(test a, test b)
{
    return test(a.i+b.i);
}

int main() {
    
    test a(100);
    a = 2+a;

    return 0;
}



Hier ist die Konvertierung in beiden Richtungen möglich und schon geht's schief.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
09.11.2004, 16:01 Uhr
Tommix




Zitat von (un)wissender:
Das war auf einen allgemeinen Ansatz bezogen. Ich sag ja, hier konkret kann es der Compiler tun, wenn er es denn könnte.

Für den speziellen Spezialfall hast Du recht

- Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
09.11.2004, 16:09 Uhr
(un)wissender
Niveauwart


Generell schwierige Sache das.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
013
10.11.2004, 17:18 Uhr
virtual
Sexiest Bit alive
(Operator)


Okay, habe mich schlau gemacht (bzw. machen lassen ):

C++:
template<typename T>
class Integer
{
        T x;
public:
        Integer(T a = 0) :x(a) { };

friend Integer operator + (const Integer& a, const Integer& b) {
        return Integer(a.x+b.x);
}
};

int main() {
        Integer<long> a;
        Integer<long> b(100);
        a = 4 + b;
}


löst das Problem.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 10.11.2004 um 17:18 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
10.11.2004, 17:34 Uhr
(un)wissender
Niveauwart


Was ist den daran jetzt so anders?
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
015
10.11.2004, 17:40 Uhr
virtual
Sexiest Bit alive
(Operator)


Die Frienddeklaration ist gleichzeitig Definition.
Das war die entscheidende Antwort:

Zitat:

Johannes Hampel" <johannes@hipphampel.de> schrieb im Newsbeitrag
news:cmr4a6$t13$1@online.de...

>> Hallo,
>>
>> gegeben sei folgendes Nonsense Template:
>>
>> template<typename T>
>> class integer {
>> T i;
>> public:
>> integer(T i_) :i(i_) { }
>>
>> friend integer<T> operator + <>(const integer<T>&, const integer<T>&;
>> };
>>
>> template<typename T>
>> integer<T> operator + (const integer<T>& a, const integer<T>& b) {
>> return integer<T>(a.i+b.i);
>> }
>>
>> int main() {
>> integer<long> a(100);
>>
>> a = ::operator +<long>(4, a); // Geht
>> a = 4 + a; // Geht nicht!
>> }
>>
>>
>> Wie zu sehen, funktioniert letzte Zeile nicht, die ja eigentlich die
>> Motivation war, den Operator als non-member zu definieren.
>> Nur weiss ich eben nicht, *warum* das nicht geht, denn bei normalen
>> Klassen geht das ja schon.
>> Geht es nicht, weil ich eineN Fehler Mache (wahrscheinlich), mein
>> Kompiler einen Fehler macht oder der Standard es einfach nicht zulaesst
>> (und wenn er es nicht zulaesst: warum laesst er es nicht zu?)


Bei Deinem Code gibt es 2 Fehler:

a) die friend - Deklaration bezieht sich auf eine nicht deklarierte
template-Funktion

Du müßtest vorher eine forward-declaration dieser Funktion machen, damit die
friend-Deklaration gültig wird.


b) Die interessante Zeile a = 4 + a;

Der Compiler kann den Typ T hier nicht ableiten, da er nur ein int
vorgesetzt kriegt.

Dein Problem hat mich animiert, den Standard nachzulesen, und nach einiger
Zeit bin ich in 14.8.2.4/2 fündig geworden:

".... Type deduction is done independently for each P/A pair, and the
deduced template arguments values are then combined. If type deduction
cannot be done for any P/A pair .... template argument deduction fails."

Ich hoffe das ist die richtige Stelle.

Demnach probiert der Compiler, aus 4 (Typ int) das T aus integer<T>
abzuleiten, was fehlschlägt, und somit ist die Zeile ungültig.


Bei
a = ::operator +<long>(4, a);
umgehst Du die Ableitung des template arguments, somit funktioniert das.


Die IMHO einfachste Lösung besteht darin, die friend-Deklaration in der
Klasse gleich auch als Definition zu nutzen:

template<typename T>
class integer {
T i;
public:
integer(T i_) :i(i_) { }
friend integer operator +(const integer& a, const integer& b) {return
integer(a.i+b.i);}
};


Dann funktioniert die betreffende Zeile, da mit dieser friend-Definition
gleichzeitig eine Überladung von operator+ mit dem jeweiligen
Instanzierungstyp bereitgestellt wird, und template argument deduction
wegfällt und nur mehr die Überladungsregeln zum Zug kommen (da wird dann der
implizite Konvertierungskonstruktor von integer aufgerufen).


Falls der Funktionsrumpf relativ lang ist (für eine inline-Definition in der
Klasse) kannst Du einfach eine einfache Hilfsfunktion aufrufen.


Thomas

-- de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod@bud.prima.de FAQ: www.voyager.prima.de/cpp/ mailto:voyager+send-faq@bud.prima.de

--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 10.11.2004 um 17:40 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
016
10.11.2004, 18:32 Uhr
(un)wissender
Niveauwart


Also schaut der Compiler sozusagen nur mit eifach Indirektion, gut zu wissen. Na ja irgendwo muss man halt auch einen Punkt machen.
--
Wer früher stirbt ist länger tot.
 
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: