Der Versuch, zur Kompilierungszeit einen einfachen Validator zu schreiben, um zu überprüfen, ob die angegebene Anzahl in den unten definierten Bereich fällt.

template<unsigned N> struct valid {static const unsigned value = 0; };
template<0U> struct valid {static const unsigned value = 1; };
template<99U> struct valid {static const unsigned value = 1; };

template<unsigned N> struct validate
{
  static const unsigned value = valid< std::min<0U,N> >::value * 
                                valid< std::max<N,99U> >::value;
}

Das obige schlägt jedoch fehl - Fehler: Das Vorlagenargument 'min <0u, 1u>' konnte nicht in 'unsigned int' konvertiert werden. Fehler: Das Vorlagenargument 'max <1u, 99u>' konnte nicht in 'unsigned int' konvertiert werden.

Irgendwelche Ideen?

c++
1
Binu 18 Jän. 2019 im 17:57

3 Antworten

Beste Antwort

Erstens ist der obige Code kein gültiger C ++ - Code. Die Syntax, die Sie für die explizite Vorlagenspezialisierung verwenden, ist nicht korrekt (und am Ende fehlt ein Semikolon). Abgesehen davon: std::min<0U,N> und std::max<N,99U> sind Funktionen, keine Funktionsaufrufe. Sie wollten wahrscheinlich schreiben:

template<unsigned N> struct valid {static const unsigned value = 0; };
template<> struct valid<0U> {static const unsigned value = 1; };
template<> struct valid<99U> {static const unsigned value = 1; };

template<unsigned N> struct validate
{
  static const unsigned value = valid< std::min(0U,N) >::value * 
                                valid< std::max(N,99U) >::value;
};

Probieren Sie es hier aus

6
Michael Kenzel 18 Jän. 2019 im 15:22

Warum nicht einfach schreiben:

template <unsigned N, unsigned LO = 0U, unsigned HI = 99U>
struct validate : std::bool_constant< N>=LO && N<=HI >
{ /* static_assert(LO <= HI); */ };

Beachten Sie, dass jeder Wert vom Typ unsigned größer oder gleich 0 ist.

2
Daniel Langr 18 Jän. 2019 im 15:24

Als Alternative zu den Vorschlägen anderer können Sie mit C ++ 11 constexpr für diesen Zweck verwenden:

constexpr bool is_in_range (unsigned n, unsigned low = 0u, unsigned high = 99u) {
    return low <= n && n <= high;
}

Was Sie erzwingen können, um zur Kompilierungszeit auszuwerten (wenn alle Argumente zur Kompilierungszeit bekannt sind), indem Sie es in einem Kontext verwenden, der eine solche Bewertung erfordert, z.

static_assert(is_in_range(5u), ""); // can skip the message with C++17
2
paler123 18 Jän. 2019 im 15:59