2016-04-11 2 views
3

Angenommen, dass ich eine Funktionsschablone benötige, die verschiedene Beträge von Bitverschiebungen auf verschiedenen Integertypen durchführt. Beispiel: Wenn der Eingangswert n vom Typ char ist, führt die Funktion einige Berechnungen unter n>>2 und n<<3 durch. Wenn es short int ist, verwendet die Funktion n>>1 und n<<8. Für int geben Sie n>>11 und n<<9, und so weiter. Natürlich sind die genannten Werte nur beispielhaft und es gibt keine Korrelation zwischen ihnen und der Größe von int_type.Wie man eine Schablone mit kundenspezifischen Bitverschiebungswerten macht

Mein Vorschlag für dieses Problem war so etwas wie diese:

template <typename Num_Type = char, int s1 = 2, int s2 = 3> void test1(Num_Type &n) 
{ 
    // this is just an example code: 
    int a = n >> s1, 
     b = n << s2; 
    // do some calculations on a and b 
} 

So kann ich diese Vorlage für verschiedene Arten von Eingangswert verwenden. Aber wenn ich es kompiliere, gibt es mir mehrere Warnungen über undefiniertes Verhalten in Schichtoperationen, weil der Wert möglicherweise zu groß ist.

  • Wie kann ich Bit-Schicht-Betrieb ohne „undefiniertes Verhalten“ immer Warnungen anpassen

      :

      So kann die Frage in zwei Formen gefragt, oder

    1. Kann ich einen begrenzten Datentyp haben, sagen intlength, die nur einen bestimmten Bereich von Zahlen haben kann, sagen 0, 1, 2, ... , 31? Ich weiß, es kann dumm klingen, aber in diesem Fall kann ich die Vorlage als

      template <typename Num_Type = char, intlength s1 = 2, intlength s2 = 3> void test1(Num_Type &n) 
      

    definieren und damit der Compiler soll nicht über Verschiebungswerte beschweren.

  • +0

    Warum erhalten Sie die Warnungen? Ich meine, warum versuchst du, 'n' mit einem zu großen' s1' oder 's2' zu verschieben? – rozina

    +0

    @rozina Ich versuche nicht, es mit zu großen Werten zu verschieben, Meine beabsichtigten Werte sind klein, aber da der Verschiebungsbetrag vom Typ int ist, denkt der Compiler, dass es zu groß werden kann –

    +0

    Ich sehe. Vielleicht ist die Warnung hier nicht sinnvoll und Sie könnten sie für diese Funktion deaktivieren. Und um sicher zu sein, können Sie Behauptungen in den Funktionskörper einfügen, um zu testen, dass "s1" und "s2" nicht zu groß sind. [Clang erzeugt jedoch keine Warnungen] (http://coliru.stacked-crooked.com/a/ad90bdc4aec37f1f) – rozina

    Antwort

    0

    Die sinnvolle Möglichkeit, das Verhalten von Vorlagenfunktionen je nach Eingabetyp zu ändern, ist die Verwendung der Vorlagenspezialisierung. Zum Beispiel:

    Achten Sie auch darauf, Ihre Schichten mit zu umgeben, wenn Sie sicherstellen, dass es keinen Überlauf gibt.

    +0

    Das macht keinen Unterschied –

    0

    Ich sehe keine Notwendigkeit für Vorlagen. Alles, was Sie brauchen, ist einfach Überlastung:

    auto test(char n) { ... } 
    auto test(uint16_t n) { .. } 
    auto test(uint32_t n) { .. } 
    
    +0

    Ich weiß das. Mein Ziel ist nicht, ein Problem zu "lösen". Ich möchte wissen, wie man etwas tut –

    +0

    Und wenn der Code sehr groß ist, wird die Überlastung der Funktion ein Schmerz in den Hintern sein –

    +0

    Dann verstehe ich Ihre Frage nicht. Ich verstehe nicht was du willst. – bolov

    1

    Sie die Warnung für diese Funktion mit einem #pragma Befehl deaktivieren können, die Sie verwenden, auf dem Compiler abhängt. Sie müssen das selbst googlen.

    Edit: da Sie erwähnen Sie Visual Studio verwenden, here is a link to disable warnings. :)

    Wenn Sie die Warnung deaktivieren können Sie hinzufügen ein static_assert zu überprüfen, ob s1 und s2 in Reichweite des Num_Type sind. Ich finde es seltsam, dass Ihr Compiler das nicht selbst tut, da alles zur Kompilierzeit bekannt ist.

    template <typename Num_Type, int s1 = 2, int s2 = 3> void test1(Num_Type &n) 
    {  
        constexpr auto max = sizeof(Num_Type) * 8; 
        static_assert(s1 < max && s2 < max, "integer overflow"); 
    
        // this is just an example code: 
        int a = n >> s1, 
         b = n << s2; 
    } 
    

    Live demo

    Verwandte Themen