Mam kilka typów, które mają podtypy o tej samej nazwie każda:Niestandardowy komunikat o błędzie podczas kompilacji niezdefiniowana podtyp jest dostępne
struct TypeA {
typedef int subtype;
};
struct TypeB {
typedef float subtype;
};
a także rodzaje, które nie mają tego podtypu ale które są wykorzystywane w tym samym kontekście:
struct TypeC {
// (no subtype defined)
};
Jak mogę dodać podtyp atrapę, która daje zwyczaj skompilować komunikat o błędzie?
My (jak dotąd nieskuteczne) próba jest:
struct TypeC {
struct subtype {
static_assert(false, "Attempt to access the non-existent subtype of TypeC.");
};
};
Ale static_assert(false, ...)
nie może działać, ponieważ kompilator zgłasza błąd, nawet jeśli typ nie jest dostępne.
Jak mogę opóźnić ocenę static_assert
do czasu, w którym typ jest używany?
nieudanej próbie jest wprowadzenie obojętne enum i skonstruować wyrażenie z niego:
enum { X };
static_assert(X != X, "...");
przypadek użycia betonu: Mam klasy szablon List
który jest zdefiniowany z pod- typy head
i tail
jeśli niepusty i powinien dać błąd, jeśli używane są te podtypy jeśli jest pusty:
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;
};
Jeśli po prostu pomijam typy head
i tail
, podczas uzyskiwania dostępu, np. 3rd elementem listy, która ma wielkość 2 z kodem List<int,int>::tail::tail::head
nie daje tak miły komunikat (g ++ 4.7.2): 'head' is not a member of 'List<int>::tail {aka List<>}'
Ten przykład 'List <>' nie narzeka na 'static_assert's? Myślałem, że ciągła ekspresja musi obejmować parametr szablonu, aby uniknąć natychmiastowej oceny. – aschepler
Hmm, pozorne wyliczenie [wydaje się nie działać] (http://coliru.stacked-crooked.com/a/602ff84bdc70c08e). –
@aschepler Działa z g ++ 4.7.2, nie jest pewien innych kompilatorów czy nawet standardu. – leemes