2014-12-15 7 views
8

Vorrei creare una macro che possa confrontare 2 stringhe ed emettere un errore di compilazione se la condizione non è soddisfatta. Questo potrebbe essere come un'asserzione del tempo di compilazione.Come confrontare statisticamente due stringhe di caratteri al momento della compilazione

Non sono sicuro di come potrei farlo.

Per esempio:

STATIC_COMPARE("THIS STRING","THIS STRING") -> would emit a compile time error 
STATIC_COMPARE("THIS STRING","THIS OTHER STRING) -> wouldn't emit a compile time error. 

La macro sarebbe simile

#define STATIC_COMPARE(str1,str2) if (str1==str2) emit an error with a message 

Quindi credo che la questione si riduce ad essere in grado di confrontare le 2 stringhe in fase di compilazione.

+0

State assumendo stringa pool letterale anche legato alla [lunghezza Computing di una stringa C in fase di compilazione. È davvero un constexpr?] (Http://stackoverflow.com/q/25890784/1708801) –

risposta

8

Si può fare questo con C++ 11 utilizzando una funzione constexpr:

constexpr bool strings_equal(char const * a, char const * b) { 
    return *a == *b && (*a == '\0' || strings_equal(a + 1, b + 1)); 
} 

(See a demo)

Non è possibile fare questo prima di C++ 11, con l'avvertenza che molti compilatori compilano stringhe di stringa uguali per essere un puntatore alla stessa posizione. Su questi compilatori è sufficiente confrontare direttamente le stringhe poiché saranno entrambe valutate come uguali puntatori.

+0

@cdhowie Non è affatto banale, ma va bene. – Columbo

+0

che utilizzava coliru sullo stesso sito web. provato su clang con 1y, funziona bene. cancellerà il mio commento. –

+0

Sto cercando di far funzionare questo in Xcode - non è stato in grado di farlo. Forse c'è un altro modo per fare affermazioni statiche in quell'ambiente. Ho trovato alcune risorse ma non sono riuscito a farlo funzionare. http://en.cppreference.com/w/cpp/language/static_assert –

-1

Non penso sia possibile confrontare due valori letterali stringa in fase di compilazione con una macro.

Effettuare la valutazione macro su un normale ciclo for che confronta le stringhe, sarà probabilmente ottimizzato in una costante da un buon compilatore, se le due stringhe sono costanti.

Poiché C++ 11 può essere eseguito con una funzione constexpr anziché una macro. Dal momento che C++ 14 il constexpr può contenere un ciclo, in C++ 11 deve essere fondamentalmente una singola istruzione return <expression>. Ma può essere fatto usando un'espressione ricorsiva come nella risposta qui sotto.

+3

Con rispetto - credo che le altre risposte forniscano esplicitamente questa informazione e in modo più dettagliato; suggerire di prendere in considerazione la rimozione della risposta. – einpoklum

3

È possibile utilizzare le funzioni constexpr. Ecco il modo in C++ 14:

constexpr bool equal(char const* lhs, char const* rhs) 
{ 
    while (*lhs || *rhs) 
     if (*lhs++ != *rhs++) 
      return false; 
    return true; 
} 

Demo.

1

Questo può essere fatto in C++ 11 usando constexpr. Definendo una funzione ricorsiva è possibile verificare che la stringa sia uguale o meno.

constexpr bool isequal(char const *one, char const *two) 
{ 
    return (*one && *two) ? (*one == *two && isequal(one + 1, two + 1)) : (!*one && !*two); 
} 

static_assert(isequal("foo", "foo"), "this should never fail"); 
static_assert(!isequal("foo", "bar"), "this should never fail"); 

Questo codice che ho usato grazie a Johannes Schaub e si può vedere l'intero SO inviare here

Problemi correlati