2016-10-03 3 views
0

あまり詳しく説明しませんが、テンプレートパラメータの種類によって異なる動作をするバリデーショナルテンプレート関数を作成しました。私は本当に簡単なコンソール印刷例に実装を簡素化:上記のコードでこのtype_traitsコードはなぜ整数からポインタへのキャスト警告を出すのですか?

#include <cstdint> 
#include <cstddef> 
#include <cstdio> 
#include <cstring> 
#include <type_traits> 

void print(const char *chars) { 
    printf("%s", chars); 
} 

template<typename FirstType, typename ... OtherTypes> 
inline void print(FirstType first, OtherTypes... others); 

template<typename ... OtherTypes> 
inline void print(const char *chars, OtherTypes... others) { 
    print(chars); 
    print(" "); 

    if (sizeof...(others) == 0) { 
     print("\r\n"); 
    } 
    else { 
     print(others...); 
    } 
} 

template<typename FirstType, typename ... OtherTypes> 
inline void print(FirstType first, OtherTypes... others) { 
    char buffer[10]; 
    const char *format = nullptr; 

    if (std::is_same<int, FirstType>::value) { 
     format = "%d"; 
    } 
    else if (std::is_same<char, FirstType>::value) { 
     format = "%c"; 
    } 
    else if (std::is_pointer<FirstType>::value && (std::is_same<char*, FirstType>::value || std::is_same<const char*, FirstType>::value)) { 
     print((const char *) first, others...); 
     return; 
    } 

    if (format != nullptr) { 
     snprintf(buffer, 10, format, first); 
    } 

    print((const char *) buffer, others...); 
} 

int main() { 
    print("this is an example:", 'X'); 

    return 0; 
} 

を私はconst char*charで可変引数関数を呼び出します。しかしトラブルは、コンパイラは私に警告を与えることで、正常に動作します:

[[email protected] tm]$ g++ tm.cpp -Wall -Wextra -o tm 
tm.cpp: In instantiation of ‘void print(FirstType, OtherTypes ...) [with FirstType = char; OtherTypes = {}]’: 
tm.cpp:24:14: required from ‘void print(const char*, OtherTypes ...) [with OtherTypes = {char}]’ 
tm.cpp:52:37: required from here 
tm.cpp:40:15: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 
     print((const char *) first, others...); 
       ^~~~~~~~~~~~~~~~~~~~ 

機能が正しくのでconst char*と同じであることをcharの種類を決定しているかのように警告が、char引数に来ますconst char*のコードパスがトリガーされました。

なぜこの警告が表示され、解決するにはどうすればよいですか?
ご回答いただきありがとうございます!

答えて

1

は、なぜ私はそのブランチ内のコードはまだでこの警告に

を取得していますFirstTypeは、その分岐が実際に実行されることはありませんにもかかわらず、charときをインスタンス化します。

どうすれば修正できますか?それは、非マッチングタイプの最初の場所でコンパイルされないようにのみ、過負荷または特殊形質のうちのいくつかのタイプのために理にかなって

移動コード。

最も単純な変化が同じ効果有し、完全else if(std::is_pointer...ブランチを削除し、この過負荷を追加することである。この特定の場合において

template<typename ... OtherTypes> 
inline void print(char *chars, OtherTypes... others) { 
    print((const char *)chars, others...); 
} 
+0

をフォーマットされるように、 "、値が割り当てられます%c "確かに起こるのを待っている間違いです。 format!= nullptrをアサートする方が良いでしょう。 – UKMonkey

+0

私はあなたと同じ問題を抱えているかどうかは確信していません - 確かに、このサンプルコードには他の品質問題があります。 – Useless

+0

'もしconstexpr'がこれをより簡単にするならば、 –

関連する問題