2017-12-06 11 views
1

printfの形式をコンパイル時にチェックしようとしています。ここにコードがあります。コンパイル時に文字列を解析する - 可能であれば

#include <type_traits> 
#include <iostream> 

template <typename CHAR, typename ...ARGS> 
constexpr size_t trace_cond(CHAR fmt, ARGS&&... args) { 
    //always needs to pass 
    return 1; 
} 

template <size_t N, typename ...ARGS> 
constexpr size_t trace_cond(const char (&fmt)[N], ARGS&&... args) { 
    //return parse(fmt) == args; 
    return sizeof...(args) != 0; 
} 

#define TRACE(fmt, ...) { \ 
    static_assert(trace_cond(fmt, __VA_ARGS__), "Wrong ARGS"); \ 
    printf(fmt, ##__VA_ARGS__); \ 
} 

int main(int argc, char* argv[]) { 
    //working fine 
    TRACE("%d %d\n", 2, 3); 

    const char* format = "%d %d\n"; 
    //error 
    TRACE(format, 2, 3); 
} 

形式はコンパイル時に知られているときに、私は(static_assertを使用して)チェックをしたい、それがその後、知られていない場合は、チェックが呼び出されないべきであるか、常に

OBSを渡す:

TRACEマクロに大きなコードベースが、変更に使用されているため、 mainは変化すべきではない
  • const char *format is not declared constexpr
  • ため
    • 現在コードがコンパイルされていません

    歓迎以上ですので、私の質問は次のとおりです。 ことstatic_assertをスキップしたりfmtタイプは、私はあなたがstatic_assertに移動することによって、あなたがやりたいことができると思いconst char *

    答えて

    0

    あるとき、それは渡すようにする方法はありますtrace_cond

    #include <type_traits> 
    #include <iostream> 
    
    template <size_t C, typename CHAR> 
    size_t trace_cond(CHAR fmt) { 
        //always needs to pass 
        return 1; 
    } 
    
    template <typename ...ARGS> 
    constexpr size_t count_args(ARGS&&... args) { 
        return sizeof...(args); 
    } 
    
    template <size_t C, size_t N> 
    constexpr size_t trace_cond(const char (&fmt)[N]) { 
        // TODO, parse fmt and do the needed checks 
        static_assert(C == 3, ""); 
        return 1; 
    } 
    
    #define TRACE(fmt, ...) { \ 
        trace_cond<count_args(__VA_ARGS__)>(fmt); \ 
        printf(fmt, ##__VA_ARGS__); \ 
    } 
    
    int main(int argc, char* argv[]) { 
        // Static check - hard coded to check for 3 arguments 
        TRACE("%d %d %d\n", 2, 3, 4); 
    
        const char* format = "%d %d\n"; 
        // No checks performed 
        TRACE(format, 2, 3); 
    } 
    
    +0

    それは解析できませんでしたので、内部の関数は ''それはconstexpr'ないtrace_cond'ので、残念ながらそれは、動作しないでしょう。 –