 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Torsten Robitzki Guest
|
Posted: Mon May 24, 2004 7:59 pm Post subject: Wrapper um simple Typen |
|
|
Hallo,
ich erwische mich immer wieder dabei, für Typen wie int einen Wrapper zu
schreiben, da ich nicht möchte, das diese Integer zuweisungskompatibel
mit anderen int's sind. Neben Kopierkonstruktor und Zuweisung kommen ab
und zu auch noch nötige Operationen wie Vergleiche, Inkrement, Dekrement
etc. dazu, so das für jeden Typen einige Zeilen an Code zusammen kommen,
ohne das diese Zeilen irgend etwas besonderes machen (ausser Ärger, wenn
man sich vertippt hat).
Ich habe jetzt eine Lösung untersucht, nach der ich ein template mit
einem tag-Typen (nur so etwas wie ein Name), dem eigentlichen Datentypen
und einer Typliste mit Operationen, die ich für den Typen gerne hätte
instanziiere. Ähnlich wie policies soll die Template Klasse dann von den
Operatoren erben, nur mit dem Unterschied, das die Anzahl der policies
durch eine Typlist definiert ist und die policies Zugriff auf den
eingebetteten Wert benötigen und keine statischen Funktionen sind.
Der Wrapper (taged_type) muß also entlang der Typliste alle Operationen
erben und in einem letzten Schritt muß eine Variable des zu wrappenden
Typs in die äusserste Basisklasse eingefügt werden.
Damit entlang der Typliste geerbt werden kann, muß das Interface zu
einer Operation also in etwa so aus sehen:
template <class T, class Base>
class op : public Base {
operation....
};
Wobei der letzte Typ in der Typliste den die Variable enthält, und damit
Base nie das Ende der Liste darstellen sollte.
Damit ich nun einen int Wrapper instanziieren kann, müste ich aber denn
Basistypen einer Operation kennen :-(
class blos_ein_name {};
typedef taged_type<blos_ein_name, int,
TOOLS_TYPE_LIST2(op1 my_int;
Hat jemand eine Idee, wie man dieses Hehne - Ei Problem lösen kann? Ich
hatte daran gedacht, aus der Typlist eine Liste von Templates zu machen,
dafür fehlt mir aber im Moment auch der Anfang.
mfg Torsten
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Daniel Albuschat Guest
|
Posted: Tue May 25, 2004 6:32 am Post subject: Re: Wrapper um simple Typen |
|
|
Torsten Robitzki wrote:
--8<-----
| Quote: | Damit ich nun einen int Wrapper instanziieren kann, müste ich aber denn
Basistypen einer Operation kennen :-(
class blos_ein_name {};
typedef taged_type
TOOLS_TYPE_LIST2(op1 my_int;
Hat jemand eine Idee, wie man dieses Hehne - Ei Problem lösen kann? Ich
hatte daran gedacht, aus der Typlist eine Liste von Templates zu machen,
dafür fehlt mir aber im Moment auch der Anfang.
|
Also ich wuerde fuer template<typename T> struct operator_plus,
operator_minus, etc. plaedieren.
Hier mal ein Beispiel, das ich (ohne Typlisten) gemacht habe:
template<typename T>
class value_base {
protected:
T t;
value_base( const T &t ): t(t) { }
};
template<typename T, typename Derive>
class operator_plus: public Derive { // operator_plus sollte dann vom
// zuletzt benutzten operator
// ableiten, und nur der Allererste
// Operator von value_base (keine
// Mehrfachvererbung!).
protected:
operator_plus( const T &t ): Derive(t) { }
public:
T operator+( const T &rhs ) const
{ return rhs + t; }
};
// Tag name weggelassen
template<typename T, template
struct taged_type: public Op< T, value_base {
taged_type(): Op< T, value_base(T()){ }
taged_type( const T &t ): Op< T, value_base(t) { }
};
int main() {
taged_type<int, operator_plus> my_int;
std::cout << my_int + 10 << 'n'; // gueltig
std::cout << my_int - 10 << 'n'; // ungueltig
}
MfG,
Daniel Albuschat
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Edzard Egberts Guest
|
Posted: Wed May 26, 2004 10:22 am Post subject: Re: Wrapper um simple Typen |
|
|
Hallo Torsten,
| Quote: | ich erwische mich immer wieder dabei, für Typen wie int einen Wrapper zu
schreiben, da ich nicht möchte, das diese Integer zuweisungskompatibel
mit anderen int's sind.
|
ich begnüge mich in solchen Fällen mit einem "typedef int spezial_int;".
Das gibt bei der Zuweisung eines "Standard-Int" zwar nur eine Warnung,
aber das reicht mir.
Gruß,
Ed
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Werner Salomon Guest
|
Posted: Wed May 26, 2004 2:13 pm Post subject: Re: Wrapper um simple Typen |
|
|
Torsten Robitzki <firstname (AT) lastname (DOT) de> wrote
Hallo Torsten,
Es gibt in der boost-Library das Paket 'operators'. Siehe
<http://www.boost.org/libs/utility/operators.htm>. Ich könnte mir
vorstellen, dass das für Dich hilfreich sein kann.
Wenn Du einen eigenen Typen hast, den Du - z.B. fast wie ein int
behandeln können möchtest, so kann man sich mit Einsatz von
boost.operators einiges an Tipp-Arbeit sparen.
Einfaches Beispiel - Addition:
class I1 : boost::addable< I1 >
{
public:
I1& operator+=( const I1& ); // <- das musst Du implementieren
};
Die Ableitung von addable<> erzeugt automatisch den operator:
I1 operator+( const I1&, const I1& );
Für alle Grundrechenarten plus den Vergleichsoperatoren geht auch
z.B.:
class I3 : boost::ordered_field_operators< I3 >
{
public:
I3& operator+=( const I3& );
I3& operator-=( const I3& );
I3& operator*=( const I3& );
I3 operator/=( const I3& );
bool operator==( const I3& ) const;
bool operator<( const I3& ) const;
};
Das erzeugt dann u.a. != > >= usw.
das geht auch in Kombination mit einem anderen Typ z.B. int - aber am
besten Du schaust mal selbst in die Doku.
Ansonsten - was spricht dagegen Dir einen - oder einige wenige -
solcher Typen als Template zu basteln mit einer Tag-Struktur als
Template-Parameter - also etwa so:
struct tag_1 {}; // leere Strukturen als Tags
struct tag_2 {};
template< typename Tag >
class IX : boost:: .. was Du brauchst
{
public:
IX& operator ..
};
Dann sind
typedef IX< tag_1 > IX1;
typedef IX< tag_2 > IX2;
natürlich verschiedene Typen.
Gruß
Werner
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Wed May 26, 2004 5:29 pm Post subject: Re: Wrapper um simple Typen |
|
|
Hallo Daniel,
Daniel Albuschat wrote:
<snip>
| Quote: | Also ich wuerde fuer template<typename T> struct operator_plus,
operator_minus, etc. plaedieren.
Hier mal ein Beispiel, das ich (ohne Typlisten) gemacht habe:
template<typename T
class value_base {
protected:
T t;
value_base( const T &t ): t(t) { }
};
template
class operator_plus: public Derive { // operator_plus sollte dann vom
// zuletzt benutzten operator
// ableiten, und nur der Allererste
// Operator von value_base (keine
// Mehrfachvererbung!).
protected:
operator_plus( const T &t ): Derive(t) { }
public:
T operator+( const T &rhs ) const
{ return rhs + t; }
};
// Tag name weggelassen
template
struct taged_type: public Op< T, value_base {
taged_type(): Op< T, value_base(T()){ }
taged_type( const T &t ): Op< T, value_base(t) { }
};
int main() {
taged_type<int, operator_plus> my_int;
std::cout << my_int + 10 << 'n'; // gueltig
std::cout << my_int - 10 << 'n'; // ungueltig
}
|
ich habe jetzt ein bisschen mit den template template Parametern
herumexperimentiert, bin dann aber auf die Lösung gekommen, aus den
Operatoren Parameterlose Klassen zu machen, die ein template (mit zwei
Parametern) als member hat. Hat den Vorteil, das taged_type recht
einfach mit einer template liste instanziiert werden kann.
Falls sind das jemand angucken möchte (Anmerkungen sind willkommen):
http://www.robitzki.de/taged_type.h
Vielen Dank für die Anregung
Torsten
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Wed May 26, 2004 5:31 pm Post subject: Re: Wrapper um simple Typen |
|
|
Hallo Edzard,
Edzard Egberts wrote:
| Quote: | Hallo Torsten,
ich erwische mich immer wieder dabei, für Typen wie int einen Wrapper
zu schreiben, da ich nicht möchte, das diese Integer
zuweisungskompatibel mit anderen int's sind.
ich begnüge mich in solchen Fällen mit einem "typedef int spezial_int;".
Das gibt bei der Zuweisung eines "Standard-Int" zwar nur eine Warnung,
aber das reicht mir.
|
würde mir wahrscheinlich auch reichen, wenn mein Compiler so eine
Warnung abgibt. Ich glaube aber, das das recht dünnes Eis ist, da eine
typedef ja nur ein anderer Name für den gleichen Typen ist.
mfg Torsten
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Wed May 26, 2004 5:36 pm Post subject: Re: Wrapper um simple Typen |
|
|
Hallo Werner,
Werner Salomon wrote:
| Quote: | Torsten Robitzki <firstname (AT) lastname (DOT) de> wrote
Hallo Torsten,
Es gibt in der boost-Library das Paket 'operators'. Siehe
http://www.boost.org/libs/utility/operators.htm>. Ich könnte mir
vorstellen, dass das für Dich hilfreich sein kann.
|
ist auf jeden Fall interressant. Ich glaube aber boost::operators geht
in genau die entgegengesetzte Richtung als in die ich gehen möchte.
Boost::operators fügt einem Typen operationen zu. Ich möchte aber einem
Typen alle Operatoren nehmen um ihm dann im Gegenzug gezielt wieder ein
Paar zu geben. Man könnte das aber sicher kombinieren.
mfg Torsten
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Wed May 26, 2004 5:44 pm Post subject: Re: Wrapper um simple Typen |
|
|
Edzard Egberts wrote:
| Quote: | Hallo Torsten,
ich erwische mich immer wieder dabei, für Typen wie int einen Wrapper
zu schreiben, da ich nicht möchte, das diese Integer
zuweisungskompatibel mit anderen int's sind.
ich begnüge mich in solchen Fällen mit einem "typedef int spezial_int;".
Das gibt bei der Zuweisung eines "Standard-Int" zwar nur eine Warnung,
aber das reicht mir.
|
Das gibt nicht mal eine Warnung, da 'spezial_int' identisch zu 'int'
ist. Typen "ableiten" geht nicht, bestenfalls kannst du einen enum machen.
Ich stand heute vor einem ähnlichen Problem. Meine Quick'n'Dirty-Lösung:
#ifdef TESTING
struct fixed_point_t {
// hier alle Methoden deklarieren, die nötig sein werden,
// zum Beispiel
fixed_point_t(int);
fixed_point_t operator+(fixed_point_t);
fixed_point_t& operator+=(fixed_point_t);
fixed_point_t operator*(int);
};
#else
typedef int fixed_point_t;
#endif
Den Code mit -DTESTING compilieren, um die Typkorrektheit zu prüfen.
Dann normal compilieren, um ein ausführbares Programm zu erhalten (das
-DTESTING-Programm wäre eh nicht linkbar und nicht performant).
Der Vorteil ist einfach, dass es Unmassen Schreibarbeit spart, weil man
nur die Methoden deklariert (und nicht mal implementiert), die man
brauchen wird.
Stefan
--
Lustiges Fehlermeldung-Raten, Teil 1:
C:TEMP> type test.cpp
struct x { } a, b, c; void f() { a = b = c; }
C:TEMP> cl -c test.cpp
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Edzard Egberts Guest
|
Posted: Thu May 27, 2004 9:35 am Post subject: Re: Wrapper um simple Typen |
|
|
Hallo Stefan,
| Quote: | ich begnüge mich in solchen Fällen mit einem "typedef int spezial_int;".
Das gibt bei der Zuweisung eines "Standard-Int" zwar nur eine Warnung,
aber das reicht mir.
Das gibt nicht mal eine Warnung, da 'spezial_int' identisch zu 'int'
ist. Typen "ableiten" geht nicht, bestenfalls kannst du einen enum machen.
|
stimmt, gibt wirklich keine Warnung - habe ich wahrscheinlich mit
Zuordnung von "enum" verwechselt. <Moppermode> Wenn typedef keine
unterscheidbaren Typen generiert, hätte man doch gleich bei den Makros
bleiben können. </Moppermode> ;o)
Damit bietet mir das typedef also nur einen Anhaltspunkt für die
Verwendung des int und keine weitere Kontrolle.
Gruß,
Ed
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|