ich einige Typen haben, die mit dem gleichen Namen Untertypen haben jeweils:Benutzerdefinierte Fehlermeldung kompilieren, wenn undefinierte Subtyp zugegriffen wird
struct TypeA {
typedef int subtype;
};
struct TypeB {
typedef float subtype;
};
und auch Arten, die nicht diesen Subtyp aufweisen, aber verwendet werden, im gleichen Kontext:
struct TypeC {
// (no subtype defined)
};
Wie kann ich einen Dummy-Untertyp hinzufügen, der eine benutzerdefinierte Kompilierfehlermeldung gibt?
Meine (bisher erfolglos) versucht wird:
struct TypeC {
struct subtype {
static_assert(false, "Attempt to access the non-existent subtype of TypeC.");
};
};
Aber static_assert(false, ...)
kann nicht funktionieren, da der Compiler den Fehler, auch wenn der Typ wirft nie abgerufen.
Wie kann ich die Auswertung von static_assert
auf den Zeitpunkt verzögern, zu dem auf den Typ zugegriffen wird?
einem gescheiterten Versuch ist ein Dummy enum einzuführen und einen Ausdruck aus ihm zu konstruieren:
enum { X };
static_assert(X != X, "...");
Konkrete Anwendungsfall: Ich habe eine Klasse-template List
, die mit dem sub- definiert ist Typen head
und tail
wenn nicht leer ist, und sollte einen Fehler, wenn diese Untertypen verwendet werden geben, wenn es leer ist:
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;
};
Wenn ich einfach die Typen head
und tail
weglassen, wenn z. das dritte Element einer Liste, die Größe 2 mit dem Code hat List<int,int>::tail::tail::head
gibt das nicht so nette Nachricht (g ++ 4.7.2): 'head' is not a member of 'List<int>::tail {aka List<>}'
Das 'List <>' Beispiel beschwert sich nicht über die 'static_assert's? Ich dachte, der konstante Ausdruck erfordere einen Template-Parameter, um eine sofortige Auswertung zu vermeiden. – aschepler
Hmm, die Dummy-Enum [scheint nicht zu funktionieren] (http://coliru.stacked-crooked.com/a/602ff84bdc70c08e) entweder. –
@aschepler Es funktioniert mit g ++ 4.7.2, nicht sicher über andere Compiler oder sogar den Standard. – leemes