2017-09-27 6 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

私はできるだけコードの量を最小限に抑えるために自分自身に挑戦しようとしています。私は1つの小切手を置くことができますなぜコードの量を倍増?私はstd :: stringを使用したいが、is_sameチェックの同じフォールトに終わる。 –

答えて

2

ifステートメントは実行時構成であるため、コードはコンパイルされません。あなたはbは常にfalseであるかについて、すべての日に私に話をすることができ

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

が、コンパイラは、まだコンパイルするifブロックのtrue場合のコードを必要とします。このコードを考えてみましょう。何intのようなもののためにあなたの例で起こっていることはこれです:

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

コンパイラはstatusintときsprintf_sコンパイルを作る方法を知りません。

ソリューションは、オーバーロードを使用することです:

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

あなたが探しているものは、通常はstatic_if"Static If Condition"のD条件付きコンパイル構文に似ている)と呼ばれています。 C++のサポートはありません。まだ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); 
} 
関連する問題