Größte Klasse zur Compilezeit mit Templates finden (geht das auch schöner?)
-
So jetzt:
template <class T1, class T2 = char> class Size { public: static const unsigned long maximum = sizeof(T1) > T2::maximum ? sizeof(T1) : T2::maximum; }; template <class T> class Size<T, char> { public: static const unsigned long maximum = sizeof(T); };(man beachte das Default-Argument)
-
Du kannst die dafür ein eigenes struct erzeugen, was das ende der liste markiert. ZB so:
struct emptylist {};und das statt
charverwenden. Die Idee mit dem Default-Argument ist auch nicht schlecht. Also, emptylist könnte das Default-Argument des zweiten Template-Parameters sein.Sonst, könnte man das mit C++0x und variadischen Templates noch umgehen:
#include <iostream> #include <ostream> #include <type_traits> // std::integral_constant, std::conditional template<class...Types> struct max_size : std::integral_constant<std::size_t,0> {}; template<class T> struct max_size<T> : std::integral_constant<std::size_t,sizeof(T)> {}; template<class T, class U, class...Rest> struct max_size<T,U,Rest...> : std::conditional< ( sizeof(T) > sizeof(U) ), max_size<T,Rest...>, max_size<U,Rest...> >::type {}; int main() { std::cout << max_size<char,int,double,float>::value << std::endl; }kk
-
ipsec schrieb:
So jetzt:
template <class T1, class T2 = char> class Size { public: static const unsigned long maximum = sizeof(T1) > T2::maximum ? sizeof(T1) : T2::maximum; }; template <class T> class Size<T, char> { public: static const unsigned long maximum = sizeof(T); };(man beachte das Default-Argument)
Hübsch, hübsch
besten Dank@krümelkacker:
Ich bin schon froh, dass ich überhaupt C++ verwenden kann. C++0x liegt da
in zu weiter Zukunft...
-
Sorry, hab den Strichpunkt hinter dem Struct vergessen gehabt.
Etz läufts auch mit dem empty struct.
-
Boost.MPL hat sowas:
#include <boost/mpl/max_element.hpp> #include <boost/mpl/sizeof.hpp> #include <boost/mpl/transform_view.hpp> #include <boost/mpl/vector.hpp> #include <cstddef> #include <iostream> int main() { using namespace boost::mpl; std::size_t n = sizeof(deref<max_element<transform_view<vector<int, char, double>, sizeof_<_1> > >::type::base>::type); std::cout << n << std::endl; }bzw.
typedef vector<int, char, double> types; typedef max_element<transform_view<types, sizeof_<_1> > >::type iter; std::size_t n = sizeof(deref<iter::base>::type);Das lässt sich dann wunderbar in boost::aligned_storage o.ä. stopfen. Wenn du zwischen mehr als 20 Typen wählen willst, musst du BOOST_MPL_LIMIT_VECTOR_SIZE vor den #includes entsprechend höher definieren.
-
Hallo

Ich hab dieses Problem schon mal mit unions gelöst...
typedef char NullType; template<class C1, class C2 = NullType, class C3 = NullType, class C4 = NullType, class C5 = NullType, class C6 = NullType> struct MaxClassSize { union { C1 c1; C2 c2; C3 c3; C4 c4; C5 c5; C6 c6; }; };sizeof(MaxClassSize<A, B, C>) sollte damit die größte Größe zurückliefern ... ist aber zugegeben etwas veraltet.
Ich hab mir das nun nochmals durch den Kopf gehen lassen und bin auf eine andere Verknüpfung gekommen, die zumindest mein VC durchgelassen hat. Gebe aber keine Garantien ab

template<class C1, class C2, bool FIRST> struct SelectType; template<class C1, class C2> struct SelectType<C1, C2, true> { typedef C1 Type; }; template<class C1, class C2> struct SelectType<C1, C2, false> { typedef C2 Type; }; template<class C1, class C2> struct IsGreaterType { static const bool Value = sizeof(C1) > sizeof(C2); }; template<class T> struct GetMaxTypeOf { typedef T Type; typedef GetMaxTypeOf<T> And; template<class T2> struct Of { typedef typename SelectType<T, T2, IsGreaterType<T, T2>::Value >::Type Type; typedef GetMaxTypeOf<Type> And; }; };ist dann etwas länger zu schreiben, aber vielleicht etwas lesbarer.
sizeof(GetMaxTypeOf<int>::And::Of<float>::And::Of<char>::And::Of<double>::Type)cu
-
geht das nicht mit nem union viel einfacher?
das template musst du halt dann x-mal überladen - da lässt sich aber vll was mit boost preprocessor machen...bb
edit: klasse - 2h lang nen tab nicht aktualisiert - sry^^
-
Du kriegst nur POD-Typen in eine Union gequetscht.
-
seldon schrieb:
Du kriegst nur POD-Typen in eine Union gequetscht.
wo steht das? oO
ich glaube nicht, dass das stimmt...bb
-
Oh, stimmt @seldon
template<class C1, class C2 = NullType, class C3 = NullType, class C4 = NullType, class C5 = NullType, class C6 = NullType> struct MaxClassSize { union { char c1[sizeof(C1)]; char c2[sizeof(C2)]; char c3[sizeof(C3)]; char c4[sizeof(C4)]; char c5[sizeof(C5)]; char c6[sizeof(C6)]; }; };Mir fällt aber dabei wieder mein Alignment-Problem ein, und deshalb wird einem die union-Methode nicht wirklich viel bringen. Man brauch für das char-Array auf jeden Fall das größte Alignment aller Typen ... Also kommt man an den echten Typen wohl nicht herum :p
Ok ... union funkioniert nicht sicher.
-
ISO/IEC 14882:2003 9.5 (1) schrieb:
An object of a class with a non-trivial constructor (12.1), a non-trivial copy constructor (12.8), a non-trivial destructor (12.4), or a non-trivial copy assignment operator (13.5.3, 12.8) cannot be a member of a union, nor can an array of such objects.
xors Workaround funktioniert insofern, als dass der größte Typ in der Aufzählung auf jeden Fall in die union passt. Für viele Use-Cases dürfte das völlig ausreichend, obwohl ich mir jetzt nicht sicher bin, ob dabei Speicher verschwendet würde. Trotzdem gefällt mir die GetMaxTypeOf-Idee besser.