2017-09-27 14 views
0

입력 템플릿을 기반으로 함수를 만들려고합니다. 파일을 읽습니다.템플릿 함수의 데이터 유형 확인

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); } 
} 

기본적으로 원하는 입력이 char인지 확인하고 있습니다. 그렇다면 우리는 읽은 char을 복사 할 것이지만 그렇지 않다면 우리는 bool/int/float/double을 복사 할 것입니다. 어쩌면 난 그냥 std :: is_same 잘못 사용하고 있습니다.

내 코드는 수표를 인식하지 못하기 때문에 컴파일되지 않으며 항상 true를 반환하는 것처럼 보입니다.

+0

가능한 경우 언제든지 'std :: string'을 사용하도록 유도하십시오. 벌거 벗고 변경 가능한 문자 버퍼는 문제가 아닙니다. – tadman

+0

템플릿 함수를 사용하는 대신에,'float'과'int'에 대한 구현을 제공하지 않을까요? – tadman

+0

나는 가능한 한 코드의 양을 최소화하기 위해 스스로에게 도전하려고 노력하고있다. 하나의 수표를 넣을 수있는 이유는 무엇입니까? 나는 std :: string을 사용할 것이지만 is_same 체크에서 같은 결점을 보게된다. –

답변

2

if 문이 런타임 구성이므로 코드가 컴파일되지 않습니다. 이 코드를 고려하십시오

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

당신은 나에게 b 항상 false이지만, 컴파일러는 여전히 컴파일 할 if 블록의 true 경우에 코드가 필요합니다 방법에 대한 모든 일을 이야기 할 수 있습니다. 컴파일러는 statusintsprintf_s 컴파일을하는 방법을 알고하지 않습니다

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); } 
} 

: 어떤 int 같은 뭔가를 당신의 예에서 일어나고있는 것은 이것이다.

이 솔루션은 오버로드를 사용하는 것입니다

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); 
} 

당신이 보통의 (a "Static If Condition"의 D 조건부 컴파일 구조와 유사) static_if라고 찾고있는 것. C++ 17에서는 지원이 없으며 C++ 2a (아직)에 대해서는 계획되어 있지 않지만 this question에 대한 응답으로 쉽게 에뮬레이트 할 수 있습니다.

#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); 
}