Probleme bei Tutorial (Programm zur Auflistung aller Primzahlen von 1 bis 100)


  • Mod

    Kellerautomat schrieb:

    http://ideone.com/tswvnMan möge mir das überschüssige Whitespace am Ende verzeihen.

    Sehr schöne Buchlösung, verliert aber Stilpunkte wegen for_ 😉

    Jetzt noch bitte eine Variante, bei der die Tiefe der rekursiven Instantiierung beschränkt ist auf sagen wir 10.



  • Kellerautomat schrieb:

    Keine Ahnung, wovon du redest. Das hat damit überhaupt nichts zu tun. Hast du den Alexandrescu überhaupt gelesen? Falls nein -> großer Fehler.

    Ja, hast Recht. Seh ich mir mal an.



  • Ist std::identity() das neue void main()?

    SCNR 😉



  • Furble Wurble schrieb:

    Ist std::identity() das neue void main()?

    SCNR 😉

    ?????

    Was sagt eigentlich SeppJ dazu? 😉



  • Ich schlage

    #!/usr/bin/make -f
    
    foo: foo.cc
    	$(CXX) $(CXXFLAGS) -o $@ $+
    
    primes.inl:
    	echo \"$(shell primes 1 100)\\n\" > $@
    
    foo.cc: primes.inl
    

    in der Makefile und

    #include <iostream>
    
    int main() {
      std::cout <<
    #include "primes.inl"
        ;
    }
    

    als foo.cc vor.


  • Mod

    Kellerautomat schrieb:

    Was sagt eigentlich SeppJ dazu? 😉

    Zu was genau? Dein Programm? Cool. 👍 Ganz schön viel Mühe. Die Kritik ist doch Pillepalle.

    Jetzt müsstest du aber natürlich eigentlich noch die variadic templates durch klassische Typlisten ersetzen, da du vorher so groß davon geredet hast. 🙂



  • Ich hab' mir das schon überlegt.
    Bis zur Erzeugung des Strings sehe ich kein echtes Problem (hab's nicht implementiert, aber müsste IMO ganz gut gehen -- wenn auch die Compilezeiten sicher massiv ansteigen im Vergleich zur variadic-template Variante).

    Nur mir will einfach keine Möglichkeit einfallen ein grosses char -Array zu erzeugen ohne dabei Overloads für 1 ... N Elemente zu schreiben.
    Und naja... so ein String kann schonmal lange werden. Und ein Klassentemplate mit 1000 spezialisierungen... pfuh. Hardcore 🙂

    Dummerweise kann man ja nicht ein char[N] Array mit einem anderen char[N-1] Array + einem einzelnen char initialisieren, ohne explizit { a[0], a[1] a[2], ... a[N-1], next } zu schreiben.



  • Z.B. so:

    #include <array>
    #include <iostream>
    #include <type_traits>
    
    struct list_end
    {};
    
    template <typename Head, typename Tail>
    struct typelist
    {};
    
    template <unsigned I>
    struct unsigned_
    	: std::integral_constant<unsigned, I>
    {};
    
    template <char C>
    struct char_
    	: std::integral_constant<char, C>
    {};
    
    template <typename>
    struct length;
    
    template <typename Head, typename Tail>
    struct length<typelist<Head, Tail>>
    	: unsigned_<1 + length<Tail>::value>
    {};
    
    template <typename Head>
    struct length<typelist<Head, list_end>>
    	: unsigned_<1>
    {};
    
    template <typename>
    struct c_str;
    
    template <typename Head, typename Tail>
    struct c_str<typelist<Head, Tail>>
    {
    	static void do_(char* p)
    	{
    		*p = Head::value;
    		c_str<Tail>::do_(++p);
    	}
    };
    
    template <typename Head>
    struct c_str<typelist<Head, list_end>>
    {
    	static void do_(char* p)
    	{
    		*p = Head::value;
    		*++p = 0;
    	}
    };
    
    int main()
    {
    	typedef
    	typelist<char_<'H'>,
    	typelist<char_<'e'>,
    	typelist<char_<'l'>,
    	typelist<char_<'l'>,
    	typelist<char_<'o'>,
    	typelist<char_<','>,
    	typelist<char_<' '>,
    	typelist<char_<'W'>,
    	typelist<char_<'o'>,
    	typelist<char_<'r'>,
    	typelist<char_<'l'>,
    	typelist<char_<'d'>,
    	typelist<char_<'!'>,
    	list_end>>>>>>>>>>>>> string;
    
    	char str[length<string>::value + 1];
    	c_str<string>::do_(str);
    
    	std::cout << str;
    }
    

    -> http://ideone.com/NmCtf



  • @Kellerautomat
    Das sowas geht ist schon klar 🙂

    Ich meine ne statische, konstante Initialisierung.
    Was wo kein Code draus wird, sondern was 1:1 direkt in der ".data" Section bzw. dem Äquivalent der jeweiligen Implementierung landet.



  • Kellerautomat schrieb:

    Furble Wurble schrieb:

    Ist std::identity() das neue void main()?

    SCNR 😉

    ?????

    War beides nie Standard. Wird nur immer und immer wieder falsch gemacht, bzw. kopiert...



  • Dann eben etwas dreckiger:

    template <typename>
    struct c_str;
    
    template <typename Head, typename Tail>
    struct c_str<typelist<Head, Tail>>
    {
    	char const head = Head::value;
    	c_str<Tail> const tail;
    };
    
    template <typename Head>
    struct c_str<typelist<Head, list_end>>
    {
    	char const head = Head::value;
    	char const tail = 0;
    };
    
    int main()
    {
    	typedef
    	typelist<char_<'H'>,
    	typelist<char_<'e'>,
    	typelist<char_<'l'>,
    	typelist<char_<'l'>,
    	typelist<char_<'o'>,
    	typelist<char_<','>,
    	typelist<char_<' '>,
    	typelist<char_<'W'>,
    	typelist<char_<'o'>,
    	typelist<char_<'r'>,
    	typelist<char_<'l'>,
    	typelist<char_<'d'>,
    	typelist<char_<'!'>,
    	list_end>>>>>>>>>>>>> string;
    
    	static c_str<string> const str;
    
    	std::cout << reinterpret_cast<char const*>(&str);
    }
    

    Möglicherweise muss man dem Compiler auch noch sagen, dass er das struct packen soll, da bin ich gerade zu wenig mit dem Standard vertraut. Ideone kann leider keine Class-Member intialization, daher kann ich das leider nicht testen. 🙂


Anmelden zum Antworten