2

Ich habe folgende template metaprogramming Umsetzung faktoriellen:Druck statische Variable für Metaprogrammierung

#include <iostream> 

template <int n> struct factorial{ 
    static const int res = n*factorial<n-1>::res; 
}; 

template <> struct factorial<0>{ 
    static const int res = 1; 
}; 

int main(){ 
    std::cout << factorial<5>::res << '\n'; 
    return 0; 
} 

Dieser Code erfolgreich kompiliert und gibt 120, wie erwartet. Aus rein selbstvergnüglichen Gründen möchte ich es stattdessen nicht kompilieren lassen und stattdessen 120 in der Fehlermeldung des Compilers anzeigen.

Gibt es einen einfachen Syntaxfehler, den ich absichtlich in meinen Code eingeben kann, damit er nicht kompiliert wird und trotzdem den Wert 5, d. H. 120, in der Compiler-Fehlermeldung ausgibt?

Ich nehme an, dass die Antwort wahrscheinlich Compiler-abhängig sein wird; Ich verwende derzeit g ++, das mit Xcode Mac OSX geliefert wurde, dessen Oberfläche ein Frontend für den Klang ist.

+1

Wenn Sie erlauben '-Werror', das tut es. http://coliru.stacked-crooked.com/a/34dfcdcb110e9bc4 'static_assert' kann hilfreich sein, wenn das nicht betrügt. –

+0

@BaummitAugen: ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ –

+0

@LightnessRacesinOrbit Nun, ich denke nach [dieser Kommentar] (https://stackoverflow.com/questions/36697980/is-it-possible-initialize-a-vector-mit-steigenden-werten-in-einzeiligen/36698222 # comment60984491_36698222) Ich kann nicht mit "vielleicht nicht nützlich sein für OP ". :) –

Antwort

4

Wenn die Option -Werror darf oder ob Warnungen gelten als Fehler, dies:

#include <iostream> 

template <int n> struct factorial{ 
    static const int res = n*factorial<n-1>::res; 
}; 

template <> struct factorial<0>{ 
    static const int res = 1; 
}; 

int main(){ 
    char x[factorial<5>::res]; 
    return x[sizeof(x)]; 
} 

wird den Fehler erzeugen/Warn

error: 'x[120ul]' is used uninitialized in this function [-Werror=uninitialized]

gcc 5.3 oder

error: array index 120 is past the end of the array (which contains 120 elements) [-Werror,-Warray-bounds]

mit Klängen 3.8.

+0

Dies ist ideal für die Anzeige von ganzen Zahlen. Ich denke, für die Anzeige eines Doppel (dh für die Vorlage Metaprogrammierung Berechnung von Pi oder etwas) Ich kann nur etwas wie 'statische char c = x', die eine Warnung drucken, wenn X ist keine ganze Zahl – xdavidliu

+0

@xdavidliu ich nicht tun Ich weiß, wie man das macht, wenn ich 'doppelt' von meinem Kopf höre und ich werde schlafen gehen. Sie können das als Follow-up-Frage einfach posten, wenn niemand antwortet, fühlen Sie sich frei, mich hier mit einem Link anzumelden, und ich werde morgen darüber nachdenken. Ihre Idee wird wahrscheinlich nur die Typen einschließen, nicht den Wert, aber sehen Sie selbst. –

5

Sie könnten eine deklarierte, aber nicht definierte Vorlage verwenden, um den Wert als Kompilierzeitfehler auszugeben.

template<int n> 
class display; 

template<int n> struct factorial{ 
    static const int res = n*factorial<n-1>::res; 
}; 

template<> struct factorial<0>{ 
    static const int res = 1; 
}; 

int main() 
{ 
    display<factorial<5>::res> value; 
} 

g ++ Ausgänge:

g++ -std=c++11 fact.cxx 
fact.cxx: In function ‘int main()’: 
fact.cxx:14:29: error: aggregate ‘display<120> value’ has incomplete type and cannot be defined 
    display<factorial<5>::res> value; 
          ^