2013-08-13 10 views
5

Ho un codice generico che deve eseguire un'asserzione sul risultato di una funzione membro. Questa funzione membro potrebbe essere constexpr o potrebbe non esserlo.Una macro assert che si espande in static_assert quando possibile?

template<typename T> 
void foo(T t) { 
    assert(t.member_function() == 10); 
} 

Perché t.member_function()potrebbe essere un'espressione costante, mi chiedo se è possibile essere trattato come un static_assert in questi casi, ma per il resto di default ad un normale assert. È possibile?

+1

Simile a http://stackoverflow.com/q/11441302/560648. Non sono sicuro che sia applicabile. –

+3

http://stackoverflow.com/q/6939103/560648 è più vicino e [la risposta è "no"] (http://stackoverflow.com/a/6941680/560648). –

+1

[stackoverflow.com/questions/18648069](http://stackoverflow.com/questions/18648069/g-doesnt-compile-constexpr-function-with-assert-in-it) è ancora più vicino e dice "sì ma " –

risposta

1

Questa è una soluzione un po 'pazza.

Decommenta la riga Const c; foo(c); e vedrai che non verrà compilata. Questa è l'asserzione in fase di compilazione.

Richiede variable length arrays e forse altri componenti specifici del compilatore. Sono su g ++ - 4.6.

La dimensione dell'array è 0 o -1, a seconda che la funzione membro restituisca 10. Quindi, se questo può essere calcolato in fase di compilazione, la compilazione si rende conto che è una matrice di lunghezza non variabile e che ha una dimensione negativa. La dimensione negativa consente di lamentarsi. Altrimenti, cade in una dichiarazione convenzionale.

Nota: sto scaricando del core con la versione di runtime subito dopo che l'asserzione di runtime fallisce. Forse non mi piace provare a free un array con dimensioni negative. Aggiornamento: sto ottenendo core dump con qualsiasi errore di asserzione, anche int main() {assert (1==2);}. È normale?

#include <iostream> 
#include <cassert> 
using namespace std; 

struct Const { 
     constexpr int member_function() { return 9; } 
}; 
struct Runtime { 
        int member_function() { return 9; } 
}; 

template<typename T> 
void foo(T t) { 
     if(0) { // so it doesn't actually run any code to malloc/free the vla 
      int z[(t.member_function()==10)-1]; // fails at compile-time if necessary 
     } 
     assert(t.member_function()==10); 
} 


int main() { 
     //Const c; foo(c); 
     Runtime r; foo(r); 
} 
Problemi correlati