2017-09-27 3 views
0

Ich versuche, eine Funktion basierend auf Eingabevorlage zu machen. Es liest eine Datei.Überprüfen der Datentypen der Template-Funktion

template<class size> void config::readConfig(char * setting, char * subsetting, size & status) { 
    char temp[255]; 
    if (!GetPrivateProfileStringA(setting, subsetting, nullptr, temp, 255, cfg)) { 
     error = true; 
    } 
    if (std::is_same<size, char [4]>::value) { 
     sprintf_s(status, "%s", temp); 
    } else { status = atof(temp); } 
} 

Ich überprüfe im Grunde nur, wenn der gewünschte Eingang ein Zeichen ist. Wenn dies der Fall ist, kopieren wir das gelesene Zeichen, aber wenn nicht, kopieren wir das bool/int/float/double. Vielleicht verwende ich nur std :: is_same falsch.

Mein Code wird nicht kompiliert, weil es nicht so aussieht, als würde es die Prüfung erkennen und es scheint, als ob es immer wahr zurückgibt.

+0

Versuchen Sie, wann immer Sie können, mit 'std :: string' zu steuern. Bare, veränderbare Zeichenpuffer sind nichts als Ärger. – tadman

+0

Anstatt eine Template-Funktion zu verwenden, warum bieten Sie nicht eine Implementierung für 'float' und eine für' int' an? – tadman

+0

Ich versuche mich selbst herauszufordern, die Menge an Code so gering wie möglich zu halten. Warum verdoppeln Sie die Menge an Code, wenn ich einen Scheck einreichen kann? Ich würde std :: string verwenden, aber ich lande am gleichen Fehler in der is_same-Prüfung –

Antwort

2

Ihr Code wird nicht kompiliert, weil eine if-Anweisung ein Laufzeitkonstrukt ist. Betrachten Sie diesen Code:

int foo(bool b) 
{ 
    if (b) 
    { 
     // attempt to call a function that does not exist 
     function_that_does_not_exist(); 
    } 
    else 
    { 
     return 1; 
    } 
} 

Sie mir den ganzen Tag darüber reden können, wie b ist immerfalse, aber der Compiler erfordert immer noch den Code in das true Fall des if Block zu kompilieren. Was ist in Ihrem Beispiel für so etwas wie ein int geschieht, ist dies:

template<> 
void config::readConfig(char* setting, char* subsetting, int& status) { 
    char temp[255]; 
    if (!GetPrivateProfileStringA(setting, subsetting, nullptr, temp, 255, cfg)) { 
     error = true; 
    } 

    // if (std::is_same<size, char [4]>::value) { 
    if (false) { 
     sprintf_s(status, "%s", temp); 
    } else { status = atof(temp); } 
} 

Der Compiler weiß nicht, wie sprintf_s Kompilierung zu machen, wenn status ein int ist.

Die Lösung ist eine Überlastung zu verwenden:

template<class size> 
void config::readConfig(char * setting, char * subsetting, size & status) { 
    char temp[255]; 
    if (!GetPrivateProfileStringA(setting, subsetting, nullptr, temp, 255, cfg)) { 
     error = true; 
    } 

    status = atof(temp); 
} 

template<size_t N> 
void config::readConfig(char* setting, char* subsetting, char (&status)[N]) { 
    char temp[255]; 
    if (!GetPrivateProfileStringA(setting, subsetting, nullptr, temp, 255, cfg)) { 
     error = true; 
    } 

    sprintf_s(status, "%s", temp); 
} 

Das Ding Sie suchen ist in der Regel als static_if (ähnlich dem D bedingte Kompilierung Konstrukt einer "Static If Condition") bezeichnet. Es gibt keine Unterstützung in C++ 17 und es ist (noch) nicht für C++ 2a geplant, aber Sie können es leicht mit der Antwort auf this question emulieren.

#include <type_traits> 

template <typename T, typename F> 
auto static_if(std::true_type, T t, F f) { return t; } 

template <typename T, typename F> 
auto static_if(std::false_type, T t, F f) { return f; } 

template <bool B, typename T, typename F> 
auto static_if(T t, F f) { return static_if(std::integral_constant<bool, B>{}, t, f); } 

template <class size> 
void config::readConfig(char* setting, char* subsetting, size& status) 
{ 
    char temp[255]; 
    if (!GetPrivateProfileStringA(setting, subsetting, nullptr, temp, 255, cfg)) 
    { 
     error = true; 
    } 

    static_if<std::is_same<size, char [4]>::value> 
    (
     [&] (auto& status) { sprintf_s(status, "%s", temp); }, 
     [&] (auto& status) { status = atof(temp); } 
    )(status); 
} 
Verwandte Themen