2017-04-19 4 views
2

Ich möchte ein conetexpr bool (useF im Beispiel unten) verwenden, um eine Funktion in den folgenden Code zu aktivieren. Hier rufen Sie A::f(). Außerdem möchte ich das Alias-Template (a) als void für den Fall sein, dass ich das Feature abschalt.Wenn conexpr (Bedingung) als Kompilierungszeit konditional

Ich habe versucht, eine constexpr if-Anweisung zu verwenden, aber der Rumpf wird immer noch instanziiert, was einen Kompilierungsfehler verursacht. Wenn ich eine Wrappervorlage verwende (X), wird der Körper wie erwartet verworfen, aber das scheint mir hässlich zu sein. Gibt es andere Möglichkeiten, dies zu tun?

constexpr bool useF = false; 

struct A { 
    static void f() {} 
}; 

using a = std::conditional<useF, A, void>::type; 

template<typename L> 
struct X { 
    static void h() { 
     if constexpr(std::is_same<L, A>::value) { 
      L::f(); // not instantiated, no error 
     } 
    } 
}; 

int main() { 
    if constexpr(useF) { 
     a::f(); // error!? 
    } 

    X<a>::h(); 
} 

ich verwende g ++ - 7.0.1 mit -std = C++ 17

+0

Entschuldigung, es gab falsche Tags Auswahl! Wenn ich das Tag C++ 17 auswähle, wird ein Tag C++ 1z eingefügt ... seltsam. – wimalopaan

+1

Weil es [Synonym] (http://stackoverflow.com/tags/c%2b%2b1z/synonyms) ist. – songyuanyao

Antwort

2

if constexpr ist nur für Vorlagen. Von [stmt.if]:

Wenn die if Anweisung der Form if constexpr, so wird der Wert der Bedingung ein kontextuell konvertiert konstanter Ausdruck des Typs seine bool (5,20); Dieses Formular wird consExpr genannt, wenn Aussage. Wenn der Wert der konvertierten Bedingung false ist, ist die erste Subanweisung eine verworfene Anweisung, andernfalls ist die zweite Unteranweisung, falls vorhanden, eine verworfene Anweisung. Während der Instanziierung einer einschließenden Vorlageneinheit (Klausel 14) wird die verworfene Subanweisung (falls vorhanden) nicht instanziiert, wenn die Bedingung nach ihrer Instanziierung nicht wertabhängig ist.

Innerhalb von X verhindert die Anweisung constexpr if die Instanziierung der ansonsten fehlerhaft erstellten Anweisung. Das ist das Ziel dieses Sprachfeatures. Aber außerhalb von Vorlagen gibt es keinen solchen äquivalenten Gewinn.

+0

Was ist schade und ich stolperte nur an der gleichen Stelle. Sie können immer einen Template-Parameter für eine Config-Bedingung angeben und dort eine Indirection hinzufügen und implementieren, aber ich verstehe die strenge Einschränkung nicht. Es liegt an Umsetzungsschwierigkeiten? –