2017-12-06 6 views
1

Ich versuche kompilieren Zeitüberprüfungen über das Format des printf. Hier ist der Code.Parsing Strings zur Kompilierzeit - wenn möglich

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

Also, wenn das Format bei der Kompilierung bekannt ist, möchte ich einen Scheck (mit static_assert) haben, und wenn es nicht bekannt ist, dann sollte die Prüfung nicht oder immer

Obs passieren aufgerufen werden:

  • Derzeit ist der Code nicht kompilieren, weil const char *format is not declared constexpr
  • die main sollte nicht geändert werden, da TRACE Makro in einer großen Code-Basis verwendet wird, aber Änderungen an TRACE sind mehr als willkommen

Also meine Frage ist: Gibt es eine Möglichkeit static_assert zu überspringen oder es passieren, wenn fmt Typ const char *

Antwort

0

ist denke ich, die Sie tun können, was Sie wollen, indem Sie die static_assert bewegen zu die 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

Leider würde es nicht funktionieren, weil innerhalb Funktion 'trace_cond' es kein' constexpr' ist, so dass es konnte nicht analysiert werden. –

Verwandte Themen