Absolute Typgrößen mit templates



  • b7f7 schrieb:

    du kannst eine Sepzialisierung in IfThenElse Weglassen und das mit dem unspezialisierten Template erschalgen.

    gute Idee, hab ich gleich mal eingebaut

    da du ja schon weisst das es Type X, Y Bits hat, sind kannst du noch ein zusätliches Dummy Templateparameter reinbaun, was auch bei gleicher Bitzahl unterschiedliche Spezialisierungen erzeugt.

    template< int size,typename DUMMYTYPE, int isSigned >
    struct BitsToType{};
    template< int isSigned >
    struct BitsToType< TypeSize::uint,int, isSigned  >{};
    template< int isSigned >
    struct BitsToType< TypeSize::ull,long, isSigned  >{};
    

    Dann müsste der Benutzer aber einen Typ für Dummytype mitangeben:
    BitsToType< 32, ???, TypeTraits::NoSign >



  • .filmor schrieb:

    Welche, #include <boost/cstdint.hpp> ? 😉

    Du weisst sicherlich, dass wir im ISO C++ Forum sind. Und boost gehört _nicht_ zum Standard. 😉 Zumal werden in <cstdint.hpp> ebenfalls recht viele Präprozessor Anweisungen verwendet. Und C's stdint.h ist dort Voraussetzung, was eine weitere Abhängigkeit bedeutet.

    s| schrieb:

    Dann müsste der Benutzer aber einen Typ für Dummytype mitangeben:
    BitsToType< 32, ???, TypeTraits::NoSign >

    Deshalb halte ich dies für keine gute Idee. So wie ich dich verstanden habe, soll man nur eine Bitgrösse angeben und der Compiler selbst den passenden Typ wählen.

    Da ich dies recht interessant finde, werde ich mir selbst mal ein paar Gedanken machen und mal schauen, ob was Sinnvolles dabei rauskommt.



  • groovemaster schrieb:

    s| schrieb:

    Dann müsste der Benutzer aber einen Typ für Dummytype mitangeben:
    BitsToType< 32, ???, TypeTraits::NoSign >

    Deshalb halte ich dies für keine gute Idee. So wie ich dich verstanden habe, soll man nur eine Bitgrösse angeben und der Compiler selbst den passenden Typ wählen.

    Genau, so hab ich mir das gedacht.


  • Mod

    da wir uns hier offensichtlich abseits der 08/15 char/short/int=8/16/32 bit in 2er komplement bewegen wären noch ein paar weitere dinge zu berücksichtigen.
    immerhin erlaubt der standard padding bits für integrale typen != [signed/unsigned] char. dann stellt sich allerdings die frage, welchen sinn die bitangabe haben soll (oder man erweitert das template auf zwei bit parameter. immerhin macht es einen unterschied, ob ich einen type haben will, der exakt 32bit zur darstellung seines wertes benötigt, oder einen, der genau 32bit im speicher verbraucht). und für vorzecihenbehaftet typen wäre noch die art der darstellung für negative typen interessant.



  • Camper, sowas würd ich gerne machen, aber mir ist kein Weg bekannt wie man das ermitteln kann 😕



  • camper schrieb:

    da wir uns hier offensichtlich abseits der 08/15 char/short/int=8/16/32 bit in 2er komplement bewegen wären noch ein paar weitere dinge zu berücksichtigen.

    Also ich würde schon erstmal eine Verwendung bei den bekannten Bitgrössen sehen. Der einzige Unterschied ist halt, dass CHAR_BIT nicht immer 8 sein muss.

    camper schrieb:

    immerhin erlaubt der standard padding bits für integrale typen != [signed/unsigned] char. dann stellt sich allerdings die frage, welchen sinn die bitangabe haben soll (oder man erweitert das template auf zwei bit parameter. immerhin macht es einen unterschied, ob ich einen type haben will, der exakt 32bit zur darstellung seines wertes benötigt, oder einen, der genau 32bit im speicher verbraucht).

    Ach ja? Was ist denn der Unterschied für dich dabei?
    Solche Gedankenspiele sind für uns doch erstmal vollkommen nebensächlich. Wir haben sizeof, was uns die Grösse in Byte liefert und CHAR_BIT, was uns die Bits pro Byte angibt. Mehr haben wir nicht und mehr brauchen wir auch erstmal nicht.

    camper schrieb:

    und für vorzecihenbehaftet typen wäre noch die art der darstellung für negative typen interessant.

    Nee, nicht im Moment. signed ist vorzeichenbehaftet, unsigned nicht. Mehr brauchen wir erstmal nicht zu wissen.



  • Im Standard (3.9.1) steht, dass die Darstellung von signed und unsigned gleich ist.
    Allerdings habe ich festgestellt, dass long int nur mindestens so groß sein muss wie short, d.h. unter Umständen können long und short gleich groß sein und char und short ebenfalls.
    Da muss ich mir noch was überlegen.



  • So habe das ganze jetzt mit Typliste und jetzt ist es egal, wenn mehrere Typen die gleiche Größe haben.

    Die Größe der Typliste wird hier nicht benötigt, ebenfalls Get und Length. Aber ohne das wäre es ja gar keine echte Typliste 😉
    Die Typliste selbst werde ich wohl mal noch erweitern, derzeit kann sie nur 4Elemente aufnehmen, da ich für die Typen nicht mehr gebraucht habe.

    Hier der Quellcode, die Anwendung ist gleich geblieben.

    template< bool condition, class TypeIfTrue, class TypeIfFalse >
    struct IfThenElse
    {
    	typedef TypeIfFalse Type;
    };
    
    template< class TypeIfTrue, class TypeIfFalse >
    struct IfThenElse< true, TypeIfTrue, TypeIfFalse >
    {
    	typedef TypeIfTrue Type;
    };
    
    struct Empty{};
    
    template< typename T1 = Empty, typename T2 = Empty,
    		  typename T3 = Empty, typename T4 = Empty > struct TypeList;
    
    template< typename T1, typename T2, typename T3, typename T4 >
    struct TypeList
    {
    	typedef T1 Head;
    	typedef TypeList< T2, T3, T4 > Tail;
    	enum
    	{
    		length = Tail::length + 1
    	};
    };
    
    template<>
    struct TypeList< Empty, Empty, Empty, Empty >
    {
    	enum
    	{
    		length = 0
    	};
    };
    
    template< typename TypeList >
    struct Length
    {
    	enum
    	{
    		val = TypeList::length
    	};
    };
    
    template< typename TypeList, int Index, int Depth = 0, 
    		  bool End = ( Index == Depth ),
    		  bool OutOfRange = Length< TypeList >::val == 0 >
    struct Get
    {
    	typedef typename Get< typename TypeList::Tail, Index, Depth + 1 >::Type Type;
    };
    
    template< typename TypeList, int Index, int Depth, bool End >
    struct Get< TypeList, Index, Depth, End, true >
    {
    };
    
    template< typename TypeList, int Index, int Depth, bool OutOfRange >
    struct Get< TypeList, Index, Depth, true, OutOfRange >
    {
    	typedef typename TypeList::Head Type;
    };
    
    #include <climits>
    
    template< typename T >
    struct TypeWrapper
    {
    	typedef T Type;
    	enum
    	{
    		size = sizeof( T ) * CHAR_BIT
    	};
    };
    
    template< typename TypeList, int size, int depth = 0,
    		  bool found = ( size == TypeList::Head::size ) >
    struct Find
    {
    	typedef typename Find< typename TypeList::Tail, size, depth + 1 >::Type Type;
    };
    
    template< typename TypeList, int size, int depth >
    struct Find< TypeList, size, depth, true >
    {
    	typedef typename TypeList::Head::Type Type;
    };
    
    typedef TypeList< TypeWrapper< unsigned char >, 
    				  TypeWrapper< unsigned short >,
    				  TypeWrapper< unsigned long >, 
    				  TypeWrapper< unsigned long long > > UnsignedIntTypes;
    
    typedef TypeList< TypeWrapper< signed char >, 
    				  TypeWrapper< signed short >,
    				  TypeWrapper< signed long >, 
    				  TypeWrapper< signed long long > > SignedIntTypes;
    
    struct TypeTraits
    {
    	enum
    	{
    		NoSign = 0,
    		WithSign = 1
    	};
    };
    
    template< int size, int isSigned >
    struct BitsToType
    {
    	typedef 
    		typename 
    			IfThenElse< isSigned,
    						typename Find< SignedIntTypes, size >::Type,
    						typename Find< UnsignedIntTypes, size >::Type >::Type Type;
    };
    
    //Anwendungsbeispiele:
    //typedef BitsToType< 8, TypeTraits::NoSign >::Type uint8;
    //typedef BitsToType< 16, TypeTraits::WithSign >::Type sint16;
    //typedef BitsToType< 32, TypeTraits::NoSign >::Type uint32;
    //typedef BitsToType< 32, TypeTraits::WithSign >::Type sint32;
    


  • Ach kommt schon sagt was dazu 🙂

    Wenn ihr nichts sagt weil ich keine Kommentare dabei stehen habe und es inzwischen doch etwas größer geworden ist, dann sagt es, die füge ich gerne dazu, wenn ich dafür ne Kritik bekomme 🙂



  • So, hab mir auch mal ein paar Gedanken gemacht und folgendes ist dabei rausgekommen:

    #include <climits>
    #include <cstddef>
    
    // tja, das gute alte if/then/else
    template <bool Condition, class Then, class Else>
    struct if_then_else;
    
    template <class Then, class Else>
    struct if_then_else<false, Then, Else>
    {
    	typedef Else result;
    };
    
    template <class Then, class Else>
    struct if_then_else<true, Then, Else>
    {
    	typedef Then result;
    };
    
    namespace native_integer
    {
    
    // unsere Typliste, mal etwas anders :)
    // leicht erweiterbar
    template <size_t I, bool Signed>
    struct type_list;
    
    template <>
    struct type_list<0, true>
    {
    	typedef signed char type;
    };
    
    template <>
    struct type_list<0, false>
    {
    	typedef unsigned char type;
    };
    
    template <>
    struct type_list<1, true>
    {
    	typedef signed short type;
    };
    
    template <>
    struct type_list<1, false>
    {
    	typedef unsigned short type;
    };
    
    template <>
    struct type_list<2, true>
    {
    	typedef signed int type;
    };
    
    template <>
    struct type_list<2, false>
    {
    	typedef unsigned int type;
    };
    
    template <>
    struct type_list<3, true>
    {
    	typedef signed long type;
    };
    
    template <>
    struct type_list<3, false>
    {
    	typedef unsigned long type;
    };
    
    // hier durchsuchen wir die Typliste nach einem passenden Eintrag
    template <size_t Size, bool Signed, size_t I = 0>
    struct type_selection
    {
    private:
    	typedef typename if_then_else<
    		sizeof(typename type_list<I, Signed>::type) * CHAR_BIT == Size,
    		type_list<I, Signed>,
    		type_selection<Size, Signed, I + 1>
    		>::result result;
    public:
    	typedef typename result::type type;
    };
    
    // Ende der Rekursion
    // private deshalb, damit wir einen Compilefehler bekommen
    template <size_t Size, bool Signed>
    struct type_selection<Size, Signed, 4>
    {
    private:
    	struct type
    	{
    	};
    };
    
    // lediglich dieses Template ist fuer den Anwender von Interesse
    template <size_t Size, bool Signed>
    struct type_definition
    {
    	typedef typename type_selection<Size, Signed>::type result;
    };
    
    } // namespace native_integer
    
    // Verwendung
    typedef native_integer::type_definition<16, false>::result uint16;
    typedef native_integer::type_definition<15, false>::result uint15; // win32: ouch
    

    Ist nur der erste Entwurf und durchaus noch verbesserungsfähig. Die Implementierung ist relativ simpel gehalten und verzichtet auf spezielle Techniken, wie Sequenzen und Iteratoren. Und wer glaubt, sein Compiler hat noch irgendwelche anderen Typen parat (wie zB long long), kann diese relativ einfach nachschieben, indem er eine weitere Spezialisierung für native_integer::type_list hinzufügt und den Index in der native_integer::type_selection Spezialisierung anpasst, um das Ende der Rekursion zu korrigieren. Theoretisch kann man auch die Spezialisierung für native_integer::type_selection auch weglassen, da am Ende der Typliste der Compiler sowieso einen Fehler bringen würde. Um unseren Compiler aber nicht zu sehr zu stressen und um die Fehlermeldungen in Grenzen zu halten, behalten wir die Spezialisierung bei.

    @s|
    Hab deinen Code mal kurz getestet und scheint zu funktionieren, obwohl ich ihn nicht bis ins Detail durchgeschaut habe. Für meinen Geschmack ist er zu kompliziert gestrickt, was aber erstmal egal ist, sofern er funktioniert. Für Lernzwecke ist er jedenfalls durchaus interessant.



  • Dein Ansatz ist nicht so viel anders wie meiner, ich habe die typelist allgemein gehalten und du hast eine speziell für den Zweck geschrieben.

    Finde deinen Ansatz prinzipiell sehr nett, aber es wäre schon, wenn du die maximale Größe automatisch ermitteln würdest, so wird das Ändern leider nen bischen zum Gefrickel.

    Bei mir ist es das derzeit zwar auch, aber ich finde diese Art von Typliste schöner, als die Rekursive, welche man zwangsweise mit nem Makro erstellen muss um den Überblick zu behalten (wird bei Loki verwendet).

    Den Find-Algo habe ich bei mir speziell für den TypeWrapper ausgelegt, das sollte auch noch verallgemeinert werden. BitsToType existiert eigentlich auch nur noch um den Sinn des ganzen zu untermauern, da ein Find leider nicht so aussagekräftig ist.

    Werde mich Morgen wohl hinsetzen und nochmal ne neue (größere) Typliste schreiben und schauen ob ich nen allgemeinen Find-Algo hinbekomme. Deine Idee mit dem überladen der Größen anhand von signed und unsigned gefällt mir, so könnte ich bei mir die zweite Typliste streichen 🙂



  • Ach eines hab ich ganz vergessen, wenn bei dir ein Typ nicht existiert, dann ist die Fehlermeldung weniger verwirrend wie bei meiner Version.
    Das muss ich bei mir auch noch ändern, aber wie gesagt will das ganze eh nochmal frisch machen, mit ner Typliste ist das eigentliche Problem bzw. Vorhaben eh keine Schwierigkeit mehr 🙂



  • Hier ist noch ein anderer Ansatz

    struct Tail{};
    template<class TElement, class TNext>
    struct  List{
    	typedef TElement Element;
    	typedef TNext Next;
    };
    
    typedef List<signed char, List<signed short, List<signed int, List<signed long, Tail> > > > SignedIntegerList;
    typedef List<unsigned char, List<unsigned short, List<unsigned int, List<unsigned long, Tail> > > > UnsignedIntegerList;
    
    template<bool yesno, class TTrue, class TFalse>
    struct IfElse;
    
    template<class TTrue, class TFalse>
    struct IfElse<true, TTrue, TFalse>{
    	typedef TTrue Result;
    };
    
    template<class TTrue, class TFalse>
    struct IfElse<false, TTrue, TFalse>{
    	typedef TFalse Result;
    };
    
    template<int bytes, class TFrom = UnsignedIntegerList>
    struct SelectInteger{
    	typedef
    	  typename IfElse<
    	    sizeof(typename TFrom::Element)==bytes,
    	    typename TFrom::Element,
    	    typename SelectInteger<bytes, typename TFrom::Next>::Result
    	  >::Result Result;
    };
    
    template<int bytes>
    struct SelectInteger<bytes, Tail>{
    	typedef void Result;
    };
    

    Erscheint mir etwas einfacher als die bisherigen Ansätze. Die Fehlermeldung des GCC ist eine Zeile groß in der er ausdrückt, dass er keine "void" Variable anlegen kann. Sollte als Fehlermeldung doch recht einfach zu verstehen sein.



  • Hier das ganz noch einmal in einer überarbeiteten Version die viel allgemeiner gehalten ist. Desweiteren ist sie besser gegliedert. Sollte also leichter verständlich sein.

    //////////////////////////
    //
    //    IfElse
    //
    template<bool yesno, class TTrue, class TFalse>
    struct IfElse;
    
    template<class TTrue, class TFalse>
    struct IfElse<true, TTrue, TFalse>{
    	typedef TTrue Result;
    };
    
    template<class TTrue, class TFalse>
    struct IfElse<false, TTrue, TFalse>{
    	typedef TFalse Result;
    };
    
    //////////////////////////
    //
    //    TypeList
    //
    struct TypeListTail{};
    template<class TElement, class TNext>
    struct  TypeList{
    	typedef TElement Element;
    	typedef TNext Next;
    };
    
    //////////////////////////
    //
    //    Default integer type lists
    //
    typedef TypeList<signed char, TypeList<signed short, TypeList<signed int, TypeList<signed long, TypeListTail> > > > SignedIntegerList;
    typedef TypeList<unsigned char, TypeList<unsigned short, TypeList<unsigned int, TypeList<unsigned long, TypeListTail> > > > UnsignedIntegerList;
    
    //////////////////////////
    //
    //    Select Type
    //
    template<class TCondition, class TFrom>
    struct SelectType{
    	typedef
    	  typename IfElse<
    	    TCondition::template Evaluate<typename TFrom::Element>::result,
    	    typename TFrom::Element,
    	    typename SelectType<TCondition, typename TFrom::Next>::Result
    	  >::Result Result;
    };
    
    template<class TCondition>
    struct SelectType<TCondition, TypeListTail>{
    	typedef void Result;
    };
    
    //////////////////////////
    //
    //    Size condition
    //
    template<int bytes>
    struct SizeCondition
    {
    	template<class T>
    	struct Evaluate{
    		static const bool result = (sizeof(T) == bytes);
    	};
    };
    
    //////////////////////////
    //
    //    TypeListUnion
    //
    template<class TTypeListA, class TTypeListB>
    struct TypeListUnion
    {
    	typedef typename TypeListUnion<
    	  typename TTypeListA::Next,
    	  TypeList<typename TTypeListA::Element, TTypeListB>
    	>::Result Result;
    };
    
    template<class TTypeListB>
    struct TypeListUnion<TypeListTail, TTypeListB>
    {
    	typedef TTypeListB Result;
    };
    
    //////////////////////////
    //
    //    SizeInteger
    //
    struct SelectIntegerSign{
    	enum{
    		unimportant,
    		no_sign,
    		sign
    	};
    };
    
    template<int bytes, int has_sign = SelectIntegerSign::unimportant>
    struct SelectInteger;
    
    template<int bytes>
    struct SelectInteger<bytes, SelectIntegerSign::no_sign>
    {
    	typedef typename SelectType<SizeCondition<bytes>, UnsignedIntegerList>::Result Result;
    };
    
    template<int bytes>
    struct SelectInteger<bytes, SelectIntegerSign::sign>
    {
    	typedef typename SelectType<SizeCondition<bytes>, SignedIntegerList>::Result Result;
    };
    
    template<int bytes>
    struct SelectInteger<bytes, SelectIntegerSign::unimportant>
    {
    	typedef typename SelectType<
    	  SizeCondition<bytes>,
    	  typename TypeListUnion<UnsignedIntegerList, SignedIntegerList>::Result
    	>::Result Result;
    };
    
    //////////////////////////
    //
    //    Example
    //
    int main()
    {
    	SelectInteger<1>::Result a;
    	SelectInteger<2, SelectIntegerSign::sign>::Result b;
    	SelectInteger<4, SelectIntegerSign::no_sign>::Result c;
    
    	typedef TypeList<unsigned long long, UnsignedIntegerList> UnsignedIntegerListWithLL;
    	SelectType<SizeCondition<8>, UnsignedIntegerListWithLL>d;
    }
    


  • Ben04 schrieb:

    Die Fehlermeldung des GCC ist eine Zeile groß in der er ausdrückt, dass er keine "void" Variable anlegen kann. Sollte als Fehlermeldung doch recht einfach zu verstehen sein.

    Mach es trotzdem so wie ich, nimm eine leere Struktur und mach sie privat. Du solltest nämlich nicht vergessen, dass es da noch void* gibt.

    Zudem versteh ich nicht ganz, wozu dein SelectIntegerSign::unimportant gut sein soll. Wenn ich das richtig sehe, sind solche Typen doch immer unsigned.



  • Zudem versteh ich nicht ganz, wozu dein SelectIntegerSign::unimportant gut sein soll. Wenn ich das richtig sehe, sind solche Typen doch immer unsigned.

    An sich ja. Die Idee war zu zeigen wie man aus 2 Listen auswählen kann. Der Code ist ja auch so gehalten, dass es leicht ist einen Type zu suchen der andere Bedingungen erfüllt. SelectIntegerSign::unimportant ist also in der Tat überflüssing.



  • hola

    interessante thematik hier. blick zwar noch net so ganz durch, aber sieht interessant aus.
    hab mir nun bissl den kopf zerbrochen wie man ohne dem CHAR_BIT aus der limits.h die bits pro bytes rausbekommen koennte. weiß nur net ob das nun so korrekt is.

    template <unsigned char x, int z = 1>
    class count_bits
    {
       public:
          enum { value = z + count_bits<x >> 1,1>::value };
    };
    
    template <int z>
    class count_bits<0,z>
    {
       public:
          enum { value = 0 };
    };
    
    const unsigned char full_byte = ~0;
    int bits_pro_byte = count_bits<full_byte>::value;
    

    scheinbar funktioniert es auch richtig. aber vielleicht kann man das ja auch noch besser loesen.
    die konstante full_byte hab ich deshalb benuetzt, weil mein BCB meckert wenn ich count_bits direkt ~0 uebergebe.
    Vielleicht kann mir ja jemand sagen, warum das so ist.

    Meep Meep



  • Probiers mit einem Cast, das könnte die Warnung des BCB beseitigen.

    int bits_pro_byte = count_bits<~(unsigned char)(0)>::value;
    

    Allerdings wundert es mich, dass es überhaupt kompiliert. Wahrscheinlich hat da jeder Compiler seine eigene Vorstellung von der Syntax Überprüfung. Mach deshalb noch Klammern in dein Template, dann sollte es überall funktionieren.

    enum { value = z + count_bits<(x >> 1),1>::value };
    

    Und bitte verwende static const, enum ist ein Hack und sollte heute nicht mehr verwendet werden. Wer sich mit Template Metaprogrammierung beschäftigt, für den sind sowieso nur aktuelle Compiler von Interesse und die sollten mittlerweile auch static const für in-class Initialisierung beherrschen.
    Ausserdem kann enum hier Probleme bereiten, zB wenn die interne Darstellung auf einer Plattform genauso gross ist wie ein char.



  • So, ich habe gestern nochmal mit den geposteten Sachen etwas rumgespielt und dies ist nun meine finale Version:

    // wieviel Bit hat ein Byte?
    template <unsigned char Value, size_t N>
    struct compute_bits_per_byte
    {
    	static const size_t result = compute_bits_per_byte<(Value >> 1), N + 1>::result;
    };
    
    template <size_t N>
    struct compute_bits_per_byte<0, N>
    {
    	static const size_t result = N;
    };
    
    // Bit-Version von sizeof
    #define bit_sizeof(x) (sizeof(x) * compute_bits_per_byte<~(unsigned char)(0), 0>::result)
    
    //
    template <class T, class Next>
    struct type_list
    {
    	typedef T type;
    	typedef Next next;
    };
    
    //
    template <bool Condition, class Then, class Else>
    struct if_then_else;
    
    template <class Then, class Else>
    struct if_then_else<false, Then, Else>
    {
    	typedef Else result;
    };
    
    template <class Then, class Else>
    struct if_then_else<true, Then, Else>
    {
    	typedef Then result;
    };
    
    //
    template <size_t Size, class Element>
    struct select_type
    {
    private:
    	typedef typename if_then_else<
    		Size == bit_sizeof(typename Element::type),
    		Element,
    		select_type<Size, typename Element::next>
    		>::result tmp;
    public:
    	typedef typename tmp::type type;
    };
    
    template <size_t Size>
    struct select_type<Size, void>
    {
    // Compilefehler falls kein Typ gefunden
    private:
    	struct type
    	{
    	};
    };
    
    template <bool Signed>
    struct integer_types;
    
    template <>
    struct integer_types<false>
    {
    	typedef
    		type_list<unsigned char,
    		type_list<unsigned short,
    		type_list<unsigned int,
    		type_list<unsigned long,
    		type_list<unsigned long long,
    		void
    		> > > > > content;
    };
    
    template <>
    struct integer_types<true>
    {
    	typedef
    		type_list<signed char,
    		type_list<signed short,
    		type_list<signed int,
    		type_list<signed long,
    		type_list<signed long long,
    		void
    		> > > > > content;
    };
    
    template <size_t Size, bool Signed>
    struct select_integer
    {
    	typedef typename select_type<Size, typename integer_types<Signed>::content>::type result;
    };
    
    typedef
    	type_list<float,
    	type_list<double,
    	type_list<long double,
    	void
    	> > > floating_point_types;
    
    template <size_t Size>
    struct select_floating_point
    {
    	typedef typename select_type<Size, floating_point_types>::type result;
    };
    
    // Bsp
    typedef select_integer<16, false>::result uint16;
    

    Wer Lust hat, kann damit auch Gleitkommatypen definieren. 🙂



  • Ah wie ich sehe sind meine Mitstreiter immer noch fleißig an der Sache dran. Habe selber in letzter Zeit leider keine Zeit mehr gehabt, da die Schule wieder angefangen hat und ich gerade im totalen Prüfungsstress bin, aber diese Woche sind die letzten Klausuren, danach habe ich wieder Zeit und werde mich auch daran setzen.

    Wobei ich, wie früher schon erwähnt, mehr auf die Typliste als auf das ursprüngliche Vorhaben konzentrieren.


Anmelden zum Antworten