Typsicheres count_of( array ) Makro
-
Manchmal bekommt man aber nunmal ein nacktes Array einfach so vorgesetzt.
-
(ungetestet)
namespace detail { template<bool b, std::size_t size> struct count_of_impl; template<std::size_t size> struct count_of_impl<true, size> { static const std::size_t value = size; } } #define count_of(array) detail::count_of_impl<boost::is_array<BOOST_TYPEOF(array)>::value, sizeof(array)/sizeof(*array)>::value
-
namespace detail { template< typename T, size_t N > int countof_assert( T ( &array )[ N ] ); } // namespace detail #define countof( array ) ( (void)sizeof(detail::countof_assert( array )), sizeof( array ) / sizeof( *array ) )
-
Probiers mal so:
namespace detail { template< typename T, size_t N > T (&countof_assert(T(&array)[N]))[N] { return array; } } // namespace detail #define countof(array) ( sizeof(detail::countof_assert(array)) / sizeof(*array))
-
jokester schrieb:
Probiers mal so:
namespace detail { template< typename T, size_t N > T (&countof_assert(T(&array)[N]))[N]; { return array; } } // namespace detail #define countof(array) ( sizeof(detail::countof_assert(array)) / sizeof(*array))
namespace detail { template< typename T, size_t N > char (&countof_assert(T(&array)[N]))[N]; } // namespace detail #define countof(array) ( sizeof(detail::countof_assert(array)))
-
LordJaxom schrieb:
Manchmal bekommt man aber nunmal ein nacktes Array einfach so vorgesetzt.
Dann kriegt man es entweder als Pointer + Größenangabe geliefert, so dass die Größe zur Compilezeit nicht zu ermitteln ist.
Wie auch immer, folgendes ließ sich zumindest auf codepad und MSVC compilieren und liefert das richtige ergebnis:
template <class T> struct count_array; template <class T, size_t N> struct count_array<T [N]> { char c[N]; }; template <class T> count_array<T> count_(T&); #define count_of(X) sizeof(count_(X))Gilt allerdings nur, wenn sizeof beim struct == sizeof char[n]
-
pumuckl schrieb:
Dann kriegt man es entweder als Pointer + Größenangabe geliefert, so dass die Größe zur Compilezeit nicht zu ermitteln ist.
Immer diese Grundsatzdiskussionen

Also gut, im konkreten Fall haben wir viele Strukturen, die COBOL-Datenfelder abbilden. Diese enthalten nur Char-Arrays, Arrays von Char-Arrays oder Arrays von Strukturen, die selbiges enthalten. Da kommt der Bedarf halt ab und zu mal hoch.
Ansonsten danke für die Lösungen, der sizeof-Trick ist genial

-
volkard schrieb:
namespace detail { template< typename T, size_t N > char (&countof_assert(T(&array)[N]))[N]; } // namespace detail #define countof(array) ( sizeof(detail::countof_assert(array)))me like it

-
LordJaxom schrieb:
Ansonsten danke für die Lösungen, der sizeof-Trick ist genial

sizeofist sowieso genial. Man kann damit die verrücktesten Dinge tun, zum Beispiel Vererbungshierarchien zur Kompilierzeit zu erkennen...
-
Jo, allgemein finde ich den Trick
sizeof(OverloadedFunction(something))ziemlich cool.
-
Jetzt fällt mir endlich wieder ein wo es beim Template-Trick hakt: der erfordert dass T ein Typ mit "external linkage" ist.
Also sowas geht damit z.B. nicht:void foo() { struct bar { ... }; bar b[123]; countof(b); // bar hat keine "external linkage" -> fehler }Was auch der Grund ist warum ich das in unserer Basis-Library jetzt doch nicht umgeschrieben habe

-
Das kommt in unserem Anwendungsfall zum Glück nicht vor...