2D Array an Methode übergeben?!
-
asfdlol schrieb:
Du kannst mal meine Version aus demselben Thread versuchen (ungetestet ehrlich gesagt):
Abgesehen von dem Off-By-One error in RecEnd scheint die zu stimmen.
Gute Idee mit remove_all_extents, das macht den Code C++11-konform.
Ich denke der Gewinner ist
template <typename T> constexpr T *flat_begin(T &x) { return &x; } template <typename T, size_t N> constexpr typename std::remove_all_extents<T>::type *flat_begin(T (&x)[N]) { return flat_begin(*x); } template <typename T> T *flat_end(T &x) { return &x + 1; } template <typename T, size_t N> constexpr typename std::remove_all_extents<T>::type *flat_end(T (&x)[N]) { return flat_begin(x[N]); }
-
@flat: Ok
#include <iterator> #include <type_traits> #define AUTO_RETURN(...) -> decltype(__VA_ARGS__) {return (__VA_ARGS__);} template <typename T> constexpr auto decayed_begin(T&& c) AUTO_RETURN(std::begin(std::forward<T>(c))) template <typename T> constexpr auto decayed_end(T&& c) AUTO_RETURN(std::end(std::forward<T>(c))) template <typename T, typename std::enable_if<std::is_array<T>::value, std::size_t>::type N> constexpr typename std::remove_all_extents<T>::type* decayed_begin(T(&c)[N]) { return decayed_begin(*c); } template <typename T, std::size_t N> constexpr auto decayed_end(T(&c)[N]) AUTO_RETURN( decayed_begin(c[N]) )?
Edit: Zu spät...
-
Arcoth schrieb:
@flat: Ok
Könntest du wenigstens deinen Code mal testen? ^Und meinen Namen richtig schreiben? Der ist weder flat_land noch flat.^
const int arr[2][3][4][5]={}; assert(flat_end(arr)-flat_begin(arr) == 2*3*4*5); std::vector<int> v[2] = {{ 1, 2, 3 }, { 4, 5, 6 }}; auto i = flat_begin(v), e = flat_end(v); assert(e - i == 2); int x = 0; assert(flat_begin(x) + 1 == flat_end(x));AUTO_RETURNist übrigens voll out.Ausserdem habe ich erörtert, wieso decayed_* die falsche Bezeichnung ist.
Das
constexprkannst du übrigens auch streichen, das funktioniert aus irgendwelchen Gründen nicht. Wahrscheinlich hat camper deshalb die Anzahl Dimensionen hardgecoded.
-
flatland schrieb:
Mr.Long schrieb:
setMatrix(reinterpret_cast<float*>(test));Kellerautomat schrieb:
Wie waere es mit &test[0][0]?
Die ultimative Lösung ist
flat_begin(test):template <typename T> T *flat_begin(T &x) { return &x; } template <typename T, size_t N> auto flat_begin(T (&x)[N]) { return flat_begin(*x); } template <typename T> T *flat_end(T &x) { return &x + 1; } template <typename T, size_t N> auto flat_end(T (&x)[N]) { return flat_begin(x[N]); }Wenn das das Problem ist, das du lösen wolltest...
flatland schrieb:
Arcoth schrieb:
@flat_land:
camper schrieb:
...Scheitert schon an dreidimensionalen Arrays, wie kann das besser sein?
Der Code ist offenbar schlecht, weil zu subtil. Im Übrigen hast du unrecht.
flatland schrieb:
Ausserdem ist decayed_begin ein misnomer, ich will von einem
int[2][3][4]aufint*und nicht aufint[2][3]*(was decayed bedeutet) oderint***(was deep_decayed bedeutet).und das heisst jetzt was?
-
Könntest du wenigstens deinen Code mal testen?
Das habe ich:
#include <iterator> #include <type_traits> #define AUTO_RETURN(...) -> decltype(__VA_ARGS__) {return (__VA_ARGS__);} template <typename T> constexpr auto decayed_begin(T&& c) AUTO_RETURN(std::begin(std::forward<T>(c))) template <typename T> constexpr auto decayed_end(T&& c) AUTO_RETURN(std::end(std::forward<T>(c))) template <typename T, typename std::enable_if<std::is_array<T>::value, std::size_t>::type N> constexpr typename std::remove_all_extents<T>::type* decayed_begin(T(&c)[N]) { return decayed_begin(*c); } template <typename T, std::size_t N> constexpr auto decayed_end(T(&c)[N]) AUTO_RETURN( decayed_begin(c[N]) ) #include <iostream> int main() { int arr[4][3][2] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89 }; std::copy( decayed_begin(arr), decayed_end(arr), std::ostream_iterator<int>{std::cout, " "} ); }Allerdings gibt es hier einen recht subtilen Ambiguitäts-Bug, der durch dein Beispiel hervorgehoben und durch
template <typename T, typename std::enable_if<std::is_array<T>::value, std::size_t>::type N> constexpr auto decayed_end(T(&c)[N]) AUTO_RETURN( decayed_begin(c[N]) )gelöst wird.
Ist dein
flat_beginaus der "Gewinnerlösung" nicht völliger Quatsch? Funktioniert bei einem Container doch gar nicht?Jetzt funktioniert auch dein Testcode, mit Ausnahme der letzten beiden Zeilen - die sind aber auch nicht sinnvoll. Eine Variable ist keine Range.
Ausserdem habe ich erörtert, wieso decayed_* die falsche Bezeichnung ist.
Ist mir egal.
Und meinen Namen richtig schreiben?
Der ist mir noch egaler.
Übrigens ist es out andere Leute penibel zu korrigieren. Es geht um Ideen und nicht um Namen.
-
AUTO_RETURNist im Übrigen ganz und gar nicht out; ist auch in C++14 für Expression-SFINAE sehr nützlich.Hier habe ich es verwendet weil ich C++11-Kompabilität haben wollte.