Du Suchst Übung!?
-
Gut, bis Gustl die Aufgabe freigeschaltet hat, hier die Kurzform:
template <typename... Ts> struct all_equal; template <typename T, typename... Ts> struct all_equal<T, Ts...> { static constexpr bool value = tmpalg::all_of<tmpalg::type_list<Ts...>, ???>::value; }; template <> struct all_equal<> : std::true_type {}; static_assert(all_equal<int, int, int, int>::value, ""); static_assert(!all_equal<float, int, int, int>::value, ""); static_assert(!all_equal<int, int, short, int>::value, ""); static_assert(all_equal<>::value, "");Ersetzte die ??? mit dem passenden Ausdruck. Es dürfen maximal 3 zusätzliche Zeilen gebraucht werden.
-
Btw: Es reichen 73 Zeichen für alles inkl ????
So schwierig ist das doch nicht.
-
Habe meine Lösung nochmal etwas überarbeitet:
template <typename T> struct identity_ { using type = T; }; template <typename T> using identity = T; template <typename... T> struct type_list : identity_<type_list<T...>> {}; template <typename... TL> struct concat_type_lists_; template <typename... TL> using concat_type_lists = typename concat_type_lists_<TL...>::type; template <typename... T, typename... U, typename... TL> struct concat_type_lists_<type_list<T...>, type_list<U...>, TL...> : concat_type_lists<type_list<T..., U...>, TL...> {}; template <typename... T> struct concat_type_lists_<type_list<T...>> : type_list<T...> {}; template <typename TL, template <typename> class Pred> struct filter_; template <typename TL, template <typename> class Pred> using filter = typename filter_<TL, Pred>::type; template <typename... T, template <typename> class Pred> struct filter_<type_list<T...>, Pred> : concat_type_lists<typename std::conditional<Pred<T>::value, type_list<T>, type_list<>>::type...> {};Eigentlich wollte ich ohne eine merge/cons/concat-Funktion auskommen. Das muss ich aber erst nochmal überschlafen.
-
templer schrieb:
Btw: Es reichen 73 Zeichen für alles inkl ????
So schwierig ist das doch nicht.Das ist es auch überhaupt nicht. Habe meine Lösung gleich fertig.
Eigentlich wollte ich ohne eine merge/cons/concat-Funktion auskommen. Das muss ich aber erst nochmal überschlafen.
Genau das dachte ich auch.

-
Btw: Wieso kann man nicht ein verschachteltes Klassentemplate as ganz normales Klassentemplate benutzen? camper, hilf!
Edit: Ach, doch es geht. Man muss nur::templateschreiben ^^So, bin fertig!
Willste sehen?
-
Sone schrieb:
So, bin fertig!
Willste sehen?Gerne. Die
::template-Lösung hatte ich ursprünglich auch (das war die Schwierigkeit).
-
Das war die Schwierigkeit? lol

template<typename T> struct all_equal_impl { template<typename InnerT> struct equal_to : public std::is_same<T, InnerT> {}; }; template <typename... Ts> struct all_equal; template <typename T, typename... Ts> struct all_equal<T, Ts...> { static constexpr bool value = tmpalg::all_of<tmpalg::type_list<Ts...>, all_equal_impl<T>::template equal_to>::value; }; template <> struct all_equal<> : std::true_type {};
-
Nice. Kommst du auch auf die Lösung mit using, die keine extra struct benötigt?
-
templer schrieb:
Nice. Kommst du auch auf die Lösung mit using, die keine extra struct benötigt?
In welcher Hinsicht? Für
all_equal_imploderall_equal?
Edit: Du wirst wohl ersteres meinen.
-
Sone schrieb:
Edit: Du wirst wohl ersteres meinen.
Erraten. Wie gesagt, die Vorlage ohne "???" mit 70 zusätzliche Zeichen (Leerzeichen mitgezählt).
-
templer schrieb:
Nice. Kommst du auch auf die Lösung mit using, die keine extra struct benötigt?
Klar:
template <typename... Ts> struct all_equal; template <typename T, typename... Ts> struct all_equal<T, Ts...> { template<typename T2> using all_equal_impl = std::is_same<T, T2>; static constexpr bool value = tmpalg::all_of<tmpalg::type_list<Ts...>, all_equal_impl >::value; }; template <> struct all_equal<> : std::true_type {};Edit: Ein bisschen eingerückt komme ich auf 65 :p (Edit²:) Mit langem Namen!
-

-
Eine weitere Aufgabe hab ich noch eingesendet:
Gegeben sind eine constexpr Funktion f und eine Zahl N
Quellcode ausblenden C-Codeconstexpr long long f(int n); // z.B. die Fakultätsfunktion const int N = 20; // Variabel, aber zur Compile-Zeit bekanntDeine Aufgabe ist es, ein Lookup-Table der Grösse N mit zur Compile-Zeit berechneten Werten zu füllen:
constexpr std::array<decltype(f(0)), N> table = ... // die Punkte sind zu ersetzen for (int i=0; i<N; ++i) assert(table[i] == f(i)); // diese Werte müssen darin seinSehr wahrscheinlich ist es nötig, weitere Funktionen und Klassen zu definieren, das ist alles erlaubt, solange das Table constexpr bleibt.
Wünschenswert, aber nicht notwendig, wäre es, wenn f und N in "..." irgendwie als Parameter übergeben werden und nicht hardgecodet sind.
Vor einem halben Jahr hab ich mal sowas gemacht.
-
Hier ein Filter ohne merge/cons/concat, dafür mit expliziter Rekursion (also quasi ein implizites merge/cons/concat):
template <typename T> struct identity_ { using type = T; }; template <typename, typename, template <typename> class> struct filter_; template <typename... L, typename M, typename... R, template <typename> class Pred> struct filter_<type_list<L...>, type_list<M, R...>, Pred> : std::conditional<Pred<M>::value, filter_<type_list<L..., M>, type_list<R...>, Pred>, filter_<type_list<L...>, type_list<R...>, Pred> >::type {}; template <typename TL, template <typename> class Pred> struct filter_<TL, type_list<>, Pred> : identity_<TL> {}; template <typename TL, template <typename> class Pred=identity> using filter = typename filter_<type_list<>, TL, Pred>::type;
-
1500 Punkte ... Platz 3
-
Verdammt! Zehn Punkte vor Platz 2!

-
Hehe, camper hat sich also doch angemeldet!

-
Ich habe jetzt noch ein filter ohne merge&co & expliziter rekursion im Algorithmus (die Rekursion steckt hier wie üblich in make_index_list und derived_tag).. Funktioniert aber leider wieder nur mit clang.
#include <type_traits> namespace tmpalg { template <typename T> struct identity_ { using type = T; }; template <typename T> using identity = T; template <typename... T> struct type_list : identity_<type_list<T...>> {}; template <int... i> struct index_list : identity_<index_list<i...>> {}; template <typename T> struct true_pred : std::true_type {}; template <int N, typename = index_list<>> struct make_index_list_; template <int N, typename T = index_list<>> using make_index_list = typename make_index_list_<N, T>::type; template <int N, int... i> struct make_index_list_<N, index_list<i...>> : make_index_list<N-1, index_list<0, 1+i...>> {}; template <int... i> struct make_index_list_<0, index_list<i...>> : index_list<i...> {}; template <int I> struct tag {}; template <typename TL> struct size_; template <typename TL> using size = typename size_<TL>::type; template <typename... T> struct size_<type_list<T...>> : std::integral_constant<int, sizeof...(T)> {}; template <typename TL, template <typename> class F> struct transform_; template <typename TL, template <typename> class F> using transform = typename transform_<TL, F>::type; template <typename... T, template <typename> class F> struct transform_<type_list<T...>, F> : type_list<F<T>...> {}; template <int I, bool b, typename T> struct helper : std::integral_constant<bool, b> { friend identity_<T> at_adl(tag<I>, helper); }; template <typename TL, template <typename> class Pred = true_pred, typename I = make_index_list<size<TL>::value>> struct apply_pred_; template <typename... T, template <typename> class Pred, int... i> struct apply_pred_<type_list<T...>, Pred, index_list<i...>> : helper<i, Pred<T>::value, T>... {}; template <typename TL, int N> struct at_ : identity_<typename decltype(at_adl(tag<N>{}, apply_pred_<TL>{}))::type> {}; template <typename TL, int N> using at = typename at_<TL, N>::type; template <int I> struct indexed_value { constexpr indexed_value(int v) : value(v) {} int value; }; template <typename TL, template <typename> class Pred = true_pred, typename I = make_index_list<size<TL>::value>> struct apply_pred; template <typename... T, template <typename> class Pred, int... i> struct apply_pred<type_list<T...>, Pred, index_list<i...>> : apply_pred_<type_list<T...>, Pred, index_list<i...>>, indexed_value<-1>, indexed_value<i>... { constexpr apply_pred() : indexed_value<-1>(0), indexed_value<i>(get<i-1>()+Pred<T>::value)... {} constexpr int count() const { return get<sizeof...(i)-1>(); } template <int I> constexpr int get() const { return indexed_value<I>::value; } }; template <int I> struct derived_tag : derived_tag<I-1> {}; template <> struct derived_tag<0> {}; template <typename TL, template <typename> class Pred, typename I = make_index_list<size<TL>::value>, typename J = make_index_list<apply_pred<TL, Pred>().count()>> struct filter_; template <typename TL, template <typename> class Pred = true_pred> using filter = typename filter_<TL, Pred>::type; template <typename TL, template <typename> class Pred, int... i, int... j> struct filter_<TL, Pred, index_list<i...>, index_list<j...>> { static constexpr apply_pred<TL, Pred> x{}; template <int x, int y> struct ordered_pair { friend constexpr int find_first(int derived_tag<x>::*, tag<y>, ordered_pair) { return x; } }; struct bimap : ordered_pair<i, x.template get<i>()>... {}; using type = type_list<at<TL,find_first(static_cast<int derived_tag<0>::*>(nullptr), tag<j+1>(), bimap())>...>; }; template <typename TL, template <typename> class Pred = true_pred> // using all_of = std::integral_constant<bool, !std::is_base_of<std::false_type, apply_pred_<TL, Pred>>::value>; using all_of = std::integral_constant<bool, apply_pred<TL, Pred>().count() == size<TL>::value>; template <typename TL, template <typename> class Pred = true_pred> // using any_of = std::is_base_of<std::true_type, apply_pred_<TL, Pred>>; using any_of = std::integral_constant<bool, apply_pred<TL, Pred>().count() != 0>; template <typename TL, template <typename> class Pred = true_pred> // using none_of = std::integral_constant<bool, !std::is_base_of<std::true_type, apply_pred_<TL, Pred>>::value>; using none_of = std::integral_constant<bool, apply_pred<TL, Pred>().count() == 0>; }
-
Yes! Zweiter!
Edit: Ach menno. Und camper hat wieder einen Bosscode.

-
Alle Achtung camper, auch dein at ist sehr elegant.