2017-07-24 9 views
0

Also mache ich ein paar Hausaufgaben, wo ich meine eigene Kompilierzeit Integer-Sequenz in C++ 11 schreiben und ein paar Funktionen dafür schreiben concat, sortiere etc.), aber ich habe ein wenig Mühe, meinen Kopf darum zu wickeln, wie ich diese Dinge schreiben würde.Drucken Compile-Zeit Integer-Sequenz in C++ 11

template<typename T, typename Comp = std::less<int>> 
struct Facility{ 

    template<T ... Nums> 
    struct List{ 

     struct Element<T ... nums>{}; 

     template<unsigned num, T val, T ... rest> 
     struct Element{ 
      unsigned index = num; 
      T value = val; 
      Element<index-1, rest...> others; 
     }; 

     template<unsigned num, T val, T ... rest> 
     struct Element<0, val>{ 
      unsigned index = 0; 
      T value = val; 
     }; 

     static constexpr Element<sizeof...(Nums)-1,Nums...> elem = {}; 

     static void Print() 
     { 
      // Prints out the list 
     } 
    }; 

}; 

using IntList = typename Facility<int>::List<intlist...>; 

int main() 
{ 
    using List1 = IntList<1, 2, 3>; 
    List1::print() 
} 

Ich würde nur gerne wissen, ob ich auf dem richtigen Weg bin, damit ich in eine Sackgasse nicht selbst arbeiten. Ich bin nicht 100% sicher auf die static print() und die static constexpr Mitglied in List, obwohl ich nicht auf andere Weise denken kann, damit es funktioniert.

Antwort

0

Ist mir nicht klar, was genau wollen Sie erhalten und die Bedeutung dessen, was Sie getan haben (warum Facility? Warum List innerhalb der Einrichtung?).

ich Ihnen nur ein Beispiel dafür, wie man ohne Rekursion schreiben Print(), eine nicht verwendete Array (und IntList definieren, wie Yakk vorgeschlagen, inspiriert von std::integer_sequence nehmen)

#include <iostream> 
#include <functional> 

template <typename T, T ... Nums> 
struct IntList 
{ 
    static void Print (std::ostream & s = std::cout) 
    { 
     using unused = int[]; 
     (void)unused { 0, ((void)(s << Nums << ", "), 0)... }; 
     s << std::endl; 
    } 
}; 

int main() 
{ 
    using List1 = IntList<int, 1, 2, 3>; 
    List1::Print(); 
} 

Wenn Sie C + verwenden können, +17 anstelle von C++ 11/C++ 14, Sie Print() ohne den ungenutzten Hack einfach schreiben können, Nums Auspacken als

folgt
static void Print (std::ostream & s = std::cout) 
    { (s << ... << (s << Nums, ", ")) << std::endl; } 

concat In Bezug auf und sortieren, ich Angenommen, Sie möchten eine Mitgliedsfunktion, die (z. B. die Konkat) eine IntList mit einer Verkettung der beiden Listen von Zahlen zurückgibt.

Die einfache concat Beispiel kann das folgende statisches Element sein für IntList

template <T ... Nums2> 
static constexpr IntList<T, Nums..., Nums2...> 
    Concat (IntList<T, Nums2...> const &) 
{ return {}; } 

So können Sie so etwas wie

constexpr IntList<int, 1, 2, 3> l1; 
constexpr IntList<int, 4, 5, 6> l2; 

constexpr auto l3 = l1.Concat(l2); 

l3.Print(); // print 1, 2, 3, 4, 5, 6, 

Ich lasse Sie die Sortierfunktion als einfache Übung :-)

schreiben
+0

Sowohl die Einrichtung als auch die Liste wurden in der Aufgabenbeschreibung bereitgestellt. Funktionen wie Sortieren usw. müssen in Facility bereitgestellt werden, während Print die einzige Funktion in List ist. Ich erkannte, dass ein Großteil meines Problems davon herrührte, dass die Liste ein tatsächliches Objekt war, wohingegen ich es als eine Kette von verketteten, von Meta-Funktionen erzeugten Strukturen hätte denken müssen. Ich denke, es sollte alles in Ordnung sein, von hier aus weiterzugehen. Danke vielmals! – ozma

4

Verschachteln Sie solche Typen nicht unnötig. Schreiben Sie eine <T,Ts...> Sequenz.

Keinen Betrieb an den Typ koppeln. Schreibe Operationen (Schwanz, Kopf) extern.

Lassen Sie sich von std::integer_sequence<T,T...> in C++ 14 inspirieren.

Wenn Sie diese Schnittstelle in der OP beschreiben müssen, schreiben Sie sie stattdessen in eine flache.

Bei weitem die einfachste Art zu schreiben ist merge sort.

Exploit std::integral_constant, die C++ 11 ist. Schreiben Sie eine Metafunktion, die einen Template-Vorlagenparameter und eine Ihrer Ganzzahllisten verwendet, und übergibt jede Integralkonstante als als Typ und generiert eine Typenliste template<class...Ts>struct types{}; als Ausgabe. Call this foreach_int

Schreiben Sie foreach_type, das eine Typenliste verwendet und ein Funktionsobjekt für jedes Element aufruft. Jetzt drucken ist trivial; template<class list> void print_list(){ foreach_type(foreach_int< idenitity, list >{}, print{}); } wo

Jeder von diesen ist leichter zu begründen, und das Komponieren sie bekommt Sie "jeden drucken".

Aber vielleicht bin ich ein bisschen verrückt.

+0

Sorry, um ganz ehrlich zu sein, habe ich Probleme, das meiste zu verstehen. Wenn Sie unnötige Verschachtelungstypen sagen, meinen Sie Facility & List? Wenn dies der Fall war, wurden beide als Teil des Zuweisungscodes bereitgestellt. Was meinen Sie mit der Kopplung von Operationen an den Typ? Und um zu verdeutlichen, flach, meinst du nicht-rekursiv? Wie Verkettung Vererbung in Tupeln? – ozma