array type deduction?
-
mit folgendem Code kann man die Größe eines C-Arrays per Deduktion ermitteln
template<typename T, int Size> int array_size(T(&)[Size]) { return Size; } int main() { int a[]={10,20,30}; return array_size(a); }
Frage:
Ich würde gerne bei für eine Template-Funktion die Größe und Typ des Arrays zur Kompilezeit ermitteln - jemand eine Idee oder geht das nicht
-
ich brauchs für C++03
-
Welches Array? Kannst du deine Frage etwas genauer stellen?
-
In C++03 wirste den Typ mittels
BOOST_TYPEOF(*a)
und die Größe mittelssizeof a / sizeof *a
bekommen müssen.
-
@roflo
das Beispiel ist doch eindeutig - oder?
-
@Arcoth
kann auf dem System leider kein Boost einsetzen
-
Gast3 schrieb:
@Arcoth
kann auf dem System leider kein Boost einsetzen
Zeig ein Beispiel. Wie soll das Ganze zum Einsatz kommen?
-
ich will einfach ein C-Array in einen Slice umwandeln
template<typename ValueType> class slice_T { private: ValueType* const _begin; ValueType* const _end; public: typedef ValueType value_type; slice_T(ValueType* const p_begin, ValueType* const p_end):_begin(p_begin),_end(p_end) { assert(_begin <= _end); } //... }; template<typename T, size_t Size> size_t array_size_T(T(&)[Size]) { return Size; } template<typename ValueType, typename ArrayType> slice_T<ValueType> make_c_array_slice(ArrayType& p_array) { static_assert(sizeof(ValueType) == sizeof(p_array[0]), "not equal size"); return slice_T<ValueType>(p_array, array_size_T(p_array)); } int main() { const uint8_t data[]={0xAA,0xBB}; auto slice = slice::make_c_array_slice<const uint8_t>(data); }
und hab gedacht ich könnte noch irgendwie die make_c_array_slice<const uint8_t> - Angabe verzichten
-
keine Idee?
-
Du bist komisch, Gast3. Du fragst danach, wie man Typ und Größe eines C-Arrays zur Compilezeit ermitteln kann und beantwortest diese Frage selbst mit dem Funktionstemplate
array_size_T
.So etwas wie slice habe ich auch in meiner Sammlung:
#include <cassert> #include <type_traits> #include <vector> #include <cstddef> #define REQUIRES_ARRAY_TYPE_CONVERTIBLE(U, T) \ ,class = typename std::enable_if< \ sizeof(T) == sizeof(U) && std::is_convertible<U*, T*>::value \ >::type template<class T> class array_ref { T* base; std::size_t len; template<class> friend class array_ref; public: array_ref(T* base, std::size_t len) : base(base) , len(len) {} template<class U REQUIRES_ARRAY_TYPE_CONVERTIBLE(U, T) > array_ref(array_ref<U> const& x) : base(x.base) , len(x.len) {} std::size_t size() const { return len; } explicit operator bool() const { return len != 0; } T* begin() const { return base; } T* end() const { return base + len; } T& operator[](std::size_t i) const { assert(i < len); return base[i]; } }; template<class T, std::size_t N> array_ref<T> aref(T (&a)[N]) { return { a, N }; } template<class T, std::size_t N> array_ref<const T> caref(const T (&a)[N]) { return { a, N }; } template<class T, class A> array_ref<const T> aref(std::vector<T, A> const& v) { return { v.data(), v.size() }; } template<class T, class A> array_ref<T> aref(std::vector<T, A> & v) { return { v.data(), v.size() }; } template<class T, class A> array_ref<const T> caref(std::vector<T, A> const& v) { return { v.data(), v.size() }; } #include <iostream> void show(array_ref<const int> ar) { for (int i : ar) { std::cout << i << '\n'; } } int main() { int a[] = {1,2,3}; show(aref(a)); return 0; }
-
Du bist komisch, Gast3. Du fragst danach, wie man Typ und Größe eines C-Arrays zur Compilezeit ermitteln kann und beantwortest diese Frage selbst mit dem Funktionstemplate array_size_T.
mir fehlt noch der Pointer auf das Array - dann wäres es perfekt
und das Template so umzuschreiben das es geht bekomme ich nicht hin#include <stddef.h> #include <cassert> template<typename ValueType> class slice_T { private: ValueType* _begin; ValueType* _end; public: typedef ValueType value_type; slice_T(ValueType* p_begin, const size_t& p_size):_begin(p_begin),_end(p_begin+p_size) { } }; template<typename T, size_t Size> size_t array_size_T(T(&)[Size]){ return Size; } template<typename ValueType, typename ArrayType> slice_T<ValueType> make_c_array_slice_ALT(ArrayType& p_array) { static_assert(sizeof(ValueType) == sizeof(p_array[0]), "not equal size"); return slice_T<ValueType>(p_array, array_size_T(p_array)); } template<typename Type, size_t Size> void make_c_array_slice_BESSER(Type p_array[Size]) { return slice_T<Type>(p_array, Size); } int a[]={1,2,3}; int main() { auto s1 = make_c_array_slice_ALT<int>(a); auto s2 = make_c_array_slice_BESSER(a); // note: candidate template ignored: // couldn't infer template argument 'Size' return 0; }
-
ich schau mal deine Code noch genauer an - Danke
-
Danke für deine Hilfe - hab meinen Fehler gefunden
-
die letzte komische Frage
warum muss man den Parametername als (&p_array) scheiben?
warum geht nicht einfach Type p_array[Size]?
ich kann gerade mit der Schreibweise gar nichts anfangen
int NAME[3]
int (&NAME)[3]das war der Fehler bei meinen Versuchen und hab es in deinem Source einfach Überlesen
-
int &x[3];
declare x as array 3 of reference to intint (&x)[3];
declare x as reference to array 3 of intmanchmal stell ich mich aber auch echt an
-
Gast3 schrieb:
warum geht nicht einfach Type p_array[Size]?
Weil das in einer Parameterliste zu nem Zeiger würde. Spezialregel die zur besseren Kompatibilität zu C aus C übernommen wurde.
void foo(int x[123]); // ist das selbe wie void foo(int* x);