Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Spezialisierung von Konversionsfunktion

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 <
000
19.01.2009, 22:20 Uhr
~DL1
Gast


Hallo,

folgendes Programm lässt sich nicht kompilieren. Das Problem liegt anscheinend bei der Spezialisierung der Konversionsfunktion. Kann mir jemand bitte sagen, was da nicht in Ordnung ist?

Es geht mir übrigens nicht darum, ein möglichst elegantes Programm zu schreiben, sondern nur darum, die korrekte Syntax zu lernen.

Für eure Hilfe vielen Dank im Voraus



C++:
#include <iostream>
using namespace std;

template <class T> class I1

{
    public:
    T i, j;
    I1(T a = 0, T b = 0): i(a), j(b){}
    ~I1(){}

    template <class U> operator I1<U>()
    {
        return I1 <U> (U(i), U(j));
    }

//problem with the following specialisation://
    template <> operator I1<char>()
    {
        cout << "char specialisation" << endl;
        return I1 <char> (char(i), char(j));
    }

};


int main()
{
    I1 <int> var2(97, 99);
    cout << var2.i << ", " << var2.j << endl;
    I1 <char> var3(var2);
    cout << var3.i << ", " << var3.j << endl;
    return 0;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
19.01.2009, 22:39 Uhr
0xdeadbeef
Gott
(Operator)


Du kannst eine Vorlage innerhalb einer nicht spezialisierten Vorlage nicht auf diese Weise spezialisieren; im Zusammenhang mit Teilspezialisierungen und/oder Spezialisierungen der umgebenden Klassenvorlage gäbe das sehr schnell sehr dreckige Probleme. Du musst die "Spezialisierung" also als normale Methode deklarieren, etwa so:

C++:
#include <iostream>
using namespace std;

template <class T> class I1

{
    public:
    T i, j;
    I1(T a = 0, T b = 0): i(a), j(b){}
    ~I1(){}

  template <class U> operator I1<U>();
  operator I1<char>();
};

template<class T>
template<class U>
I1<T>::operator I1<U>()
{
  return I1<U>(U(i), U(j));
}

template<typename T>
I1<T>::operator I1<char>() {
  cout << "char specialisation" << endl;
  return I1<char> (char(i), char(j));
}

int main()
{
    I1 <int> var2(97, 99);
    cout << var2.i << ", " << var2.j << endl;
    I1 <char> var3(var2);
    cout << var3.i << ", " << var3.j << endl;
    return 0;
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
19.01.2009, 23:04 Uhr
~DL1
Gast


Danke für die schnelle Antwort. Die Lösung mit der überladenen normalen Methode war mir schon eingefallen, mir ging es eher darum, wie man die entsprechende Spezialisierung formulieren würde. Aber wenn die Sprache die Möglichkeit gar nicht bietet, hier eine Spezialisierung zu schreiben (ist das so richtig?), kann ich gern damit leben!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
19.01.2009, 23:21 Uhr
0xdeadbeef
Gott
(Operator)


Das ist richtig, ja. Es wäre ja auch keine wirkliche Spezialisierung; sie wäre nach wie vor von einer Vorlage umgeben. Im Falle weiterer Spezialisierungen der umgebenden Klassenvorlage stellte sich die Frage, wozu die Spezialisierung denn eigentlich gehört.

Es ist kein Problem, etwas wie

C++:
template<> template<> operator I1<char>::operator<int>() { ... }


oder

C++:
template<> template<typename T> operator I1<char>::operator I1<T>() { ... }


zu schreiben, nur andersrum geht's halt nicht.

Unter diesem Gesichtspunkt, und weil Konversionsoperatoren eine recht haarige Sache sein können, würde ich mir an deiner Stelle übrigens überlegen, statt der Operatoren Konstruktoren bereitzustellen. Dann ließe sich der Konstruktor in I1<char> auf diese Weise spezialisieren, etwa so:

C++:
#include <iostream>
using namespace std;

template <class T> class I1

{
public:
  T i, j;
  I1(T a = 0, T b = 0): i(a), j(b){}
  ~I1(){}

  template<typename U> I1(I1<U> const &);
};

template<class T>
template<class U>
I1<T>::I1(I1<U> const &i1)
  : i(i1.i), j(i1.j) { }

template<>
template<typename U>
I1<char>::I1(I1<U> const &i1)
  : i(i1.i), j(i1.j)
{
  cout << "char specialisation" << endl;
}

int main()
{
    I1 <int> var2(97, 99);
    cout << var2.i << ", " << var2.j << endl;
    I1 <char> var3(var2);
    cout << var3.i << ", " << var3.j << endl;
    return 0;
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 19.01.2009 um 23:23 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
20.01.2009, 11:22 Uhr
~DL1
Gast


Danke. Ich werde mir Deine Erklärung und Beispiele durch den Kopf gehen lassen müssen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
20.01.2009, 20:46 Uhr
~DL1
Gast


Ich habe das jetzt alles verstanden, bis auf eine Frage:

Ist das jeweils erste "operator" in den Definitionen richtig?


C++:
template<> template<> operator I1<char>::operator<int>() { ... }

template<> template<typename T> operator I1<char>::operator I1<T>() { ... }

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
20.01.2009, 20:52 Uhr
0xdeadbeef
Gott
(Operator)


Der erste enthält einen Tippfehler, das sollte

C++:
template<> template<> operator I1<char>::operator I1<int>() { ... }


heißen.

Das sind dann Spezialisierungen für die Umwandlung von I1<char> nach I1<int> bzw. von I1<char> nach I1<irgendwas>.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
20.01.2009, 21:06 Uhr
~DL1
Gast


Das verstehe ich nicht ganz.

Bedeutet nicht etwa


C++:
template<> template<> operator I1<char>::operator<int>(){}




dass operator<int>(){} zum Namensbereich von operator I1<char> gehört oder eine Methode von operator I1<char> ist?

Im Programm 001 oben heißt es ja


C++:
template<class T>
template<class U>
I1<T>::operator I1<U>()
{
  return I1<U>(U(i), U(j));
}



(mit nur 1x "operator").
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
20.01.2009, 21:12 Uhr
0xdeadbeef
Gott
(Operator)


Eh, das hab ich jetzt davon, wenn ich das einfach so hintippe, ohne es zu testen. Also, jetzt nochmal richtig:

C++:
template<> template<> I1<char>::operator I1<int>() { ... }

template<> template<typename T> I1<char>::operator I1<T>() { ... }


...jetzt sollte es richtig sein. Tut mir leid, Flüchtigkeitsfehler.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
20.01.2009, 21:17 Uhr
~DL1
Gast


Kein Problem. Auf jeden Fall vielen Dank. Das hat mir wirklich weitergeholfen!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ 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: