ho alcuni tipi che hanno sotto-tipi con lo stesso nome di ciascuno:compilazione personalizzato messaggio di errore quando sottotipo definito si accede
struct TypeA {
typedef int subtype;
};
struct TypeB {
typedef float subtype;
};
e anche i tipi che non hanno questo sottotipo, ma che vengono utilizzati nello stesso contesto:
struct TypeC {
// (no subtype defined)
};
Come è possibile aggiungere un sottotipo fittizio che fornisce un messaggio di errore di compilazione personalizzato?
mio (finora senza successo) tentativo è:
struct TypeC {
struct subtype {
static_assert(false, "Attempt to access the non-existent subtype of TypeC.");
};
};
Ma static_assert(false, ...)
non può funzionare, come il compilatore genera l'errore, anche se il tipo non è mai raggiungibile.
Come posso ritardare la valutazione di static_assert
nel momento in cui si accede al tipo?
Un tentativo fallito è quello di introdurre un enum fittizio e costruire un'espressione fuori di esso:
enum { X };
static_assert(X != X, "...");
caso d'uso Calcestruzzo: Ho una classe-template List
che è definito con il sub- tipi head
e tail
se non vuoto, e dovrebbe dare un errore se vengono utilizzati questi sottotipi se vuota:
template<typename...>
struct List;
// empty list:
template<>
struct List<> {
struct head { static_assert(false, "Attempt to access the head of an empty list."); };
struct tail { static_assert(false, "Attempt to access the tail of an empty list."); };
};
// non-empty list:
template<typename Head, typename ...Tail>
struct List<Head, Tail...> {
typedef Head head;
typedef List<Tail...> tail;
};
Se ho semplicemente omesso i tipi head
e tail
, quando accedo ad es. il 3 ° elemento di una lista che ha formato 2 con il codice List<int,int>::tail::tail::head
dà il non così bel messaggio (g ++ 4.7.2): 'head' is not a member of 'List<int>::tail {aka List<>}'
Questo esempio di 'Elenco <>' non si lamenta del 'static_assert's? Ho pensato che l'espressione costante fosse necessaria per coinvolgere un parametro di modello per evitare una valutazione immediata. – aschepler
Hmm, il dummy enum [sembra non funzionare] (http://coliru.stacked-crooked.com/a/602ff84bdc70c08e). –
@aschepler Funziona con g ++ 4.7.2, non è sicuro di altri compilatori o anche dello standard. – leemes