2017-02-16 2 views
1

sagen, ich habe folgenden CodeSammen Vorlage Spezialisierungen

#include <iostream> 

template<int N> 
int calcFac() { 

    return N*calcFac<N-1>(); 
} 

template<> 
int calcFac<1>() { 

    return 1; 
} 

template<> 
int calcFac<0>() { 

    return 1; 
} 

int main() { 

    int f4 = calcFac<4>(); 
    int f5 = calcFac<5>(); 
    int f1 = calcFac<1>(); 
    int f0 = calcFac<0>(); 

    std::cout <<"4! = "<<f4<<std::endl; 
    std::cout <<"5! = "<<f5<<std::endl; 
    std::cout <<"1! = "<<f1<<std::endl; 
    std::cout <<"0! = "<<f0<<std::endl; 

    return 0; 
} 

Gibt es eine Möglichkeit (dh nicht das STL bietet ein Konstrukt) einen Topf zu werfen, die beiden Spezialfälle calcFac<0> und calcFac<1>, so dass ich nur eine Funktion benötigen für beide Fälle?

d.h .: calcFac</*if this parameter is 0 or 1 use that template function*/>

Antwort

3

Edit: Mein ursprünglicher Entwurf fehlerhaft ist (funktioniert nicht richtig mit calcFac<0>()). Ich nehme stattdessen das Design von @xaxxon. Wenn ich mein ursprüngliches Design speichern möchte, müssen drei Funktionen deklariert werden, aber die beiden Spezialfälle werden zusammengelegt. Sie können es am Ende dieser Antwort finden.

Es gibt, von SFINAE mit und std::enable_if_t

#include <type_traits> 
template <int N> 
std::enable_if_t<N <= 1, int> calcFac() { 
    return 1; 
} 

template<int N> 
std::enable_if_t<!(N <= 1), int> calcFac() { 
    return N*calcFac<N-1>(); 
} 

Wie funktionierts:

std::enable_if_t<exp, Type> entspricht Type wenn exp ist true, und nicht angemeldete anders. Durch Verwendung von auf diese Weise im Rückgabetyp wird ein Fehler verursacht, wenn expfalse ist, daher ist die Funktion außerhalb der Kandidatenliste.


#include <type_traits> 
template <int N> 
std::enable_if_t<N<=1, int> calcFacImpl(int) { 
    return 1; 
} 

template <int N> 
int calcFacImpl(...) { 
    return N*calcFacImpl<N-1>(0); 
} 

template <int N> 
int calcFac() { 
    return calcFacImpl<N>(0); 
} 
+0

verwenden, das gut aussieht – FloriHe

+2

es ist seltsam einen nicht verwendeten Parameter wie einführen das, obwohl. Etwas wie dieses: https://godbolt.org/g/epF0wQ scheint mir einfacher. Obwohl ich das wahrscheinlich mit Strukturen tun würde, funktioniert das überhaupt nicht. Etwas mehr wie: https://godbolt.org/g/PB0Agq – xaxxon

+0

Ich bin mir nicht sicher, ob "SFINAE Fehler" der richtige Begriff ist. Wenn Sie es buchstabieren, klingt es ein bisschen komisch: Substitutionsfehler ist kein Fehler Fehler ... – user463035818

0

In soon-to-be-standardisierte C++ 1z, können Sie if constexpr

template<int N> 
auto calcFac() { 
    if constexpr (N > 1) { 
     return N * calcFac<N-1>(); 
    } 
    return 1; 
} 

Live Example

Verwandte Themen