2016-03-28 5 views
0

Ich versuche, die Klasse std::bitset als Alias ​​einzugeben, wobei der Vorlagenparameter N mit einer constexpr-Funktion berechnet wird. Dieser Ansatz scheint jedoch in eine Wand zu rennen.Aufruf der consExpr-Funktion für den Bitset-Vorlagenparameter

Der Code sieht derzeit wie folgt aus:

static constexpr std::size_t ComponentCount() noexcept { 
    return 3U; 
} 

static constexpr std::size_t TagCount() noexcept { 
    return 5U; 
} 

using Bitset = std::bitset<ComponentCount() + TagCount()>; 

Und die Fehler, die ich empfangen habe, ist wie folgt:

1>error C2975: '_Bits': invalid template argument for 'std::bitset', expected compile-time constant expression 
1> note: see declaration of '_Bits' 

Vielen Dank für Ihre Hilfe.

+1

Ihr Code kompiliert für mich mit Visual Studio 2015 Update 1 und auch mit webcompiler.cloudapp.net. –

+0

Hrmm das ist sehr seltsam. Ich verwende auch Visual Studio 2015 (speziell Version 14.0.23107.0). Ich bin mir nicht sicher, ob das "Update 1" ist oder nicht. Es kann sehr gut nicht sein, angenommen, 14,1 ... würde Update 1 entsprechen. –

+0

Ich glaube, das ist RTM. Meine Version ist 14.0.24720.00. Es gab [eine Menge] (https://blogs.msdn.microsoft.com/vcblog/2015/12/02/constexpr-in-vs2015-update-1/) von conexpr Bugs, die in Update 1 behoben wurden, also gib ein Update ein Schuss. –

Antwort

0

Wie sich herausstellte, habe ich nicht genügend Kontext in meine ursprüngliche Frage aufgenommen. Das Problem endete etwas subtiler.

Hier ist eine genauere Darstellung, wie mein Code sah:

template 
< 
    typename ComponentList, 
    typename TagList, 
    typename SignatureList 
> 
struct Settings { 
    // ... 

    static constexpr std::size_t ComponentCount() noexcept { 
     return 3U; 
    } 

    static constexpr std::size_t TagCount() noexcept { 
     return 5U; 
    } 

    // ... 

    using Bitset = std::bitset<ComponentCount() + TagCount()>; 

    // ... 
}; 

Dieser Ansatz schien mir in Ordnung, und hat mich nicht mit irgendwelchen Compiler-Warnungen oder irgendetwas geben. Nur der Compiler Fehler in der ursprünglichen Frage erwähnt.

Allerdings, wenn ich das Problem weiter in einem Versuch, vereinfachte, um genauer das Problem zu isolieren, habe ich am Ende auf dem Punkt:

struct Settings { 
    static constexpr std::size_t ComponentCount() noexcept { 
     return 3U; 
    } 

    static constexpr std::size_t TagCount() noexcept { 
     return 5U; 
    } 

    using Bitset = std::bitset<ComponentCount() + TagCount()>; 
}; 

Nach dieser Vereinfachung zu tun (oder genauer gesagt, nach den Template-Parametern zu entfernen) , VS2015 hat den Fehler function call must have a constant value in a constant expression für beide Funktionsaufrufe ComponentCount() und TagCount() gefunden und rot markiert. Scheinbar kann der Compiler statische constexpr-Funktionen, die in derselben Struktur enthalten sind, nicht als konstante Ausdrücke betrachten? Seltsam. Es könnte versucht werden, den Typ-Alias ​​zu machen, bevor die const-Ausdrücke definiert werden.

Die Lösung für die Templat-Struktur war wie folgt:

using ThisType = Settings<ComponentList, TagList, SignatureList>; 

// ... 

using Bitset = std::bitset<ThisType::ComponentCount() + ThisType::TagCount()>; 

Doch dieser Ansatz funktioniert nicht für die Nicht-Template-Struktur. Siehe meine anderen StackOverflow post für verschiedene Ansätze in diesem Fall.

0

Wie in den Kommentaren von @MattWeber angezeigt, die aktuelle webcompiler.cloudapp.net mit Compiler-Version mit 19.00.23720.0 dieses kleine Testprogramm mit Ihrem Code

int main() 
{ 
    cout << Bitset{}.size() << "\n"; 
} 
8.

Ausgabe nicht greifen also nur (20. Januar 2016 gebaut) das neueste Visual Studio und überprüfen Sie die Compiler-Version (wenn es größer als 19.00.23720.0 ist, sollte es funktionieren).

Verwandte Themen