I have some types which have sub-types with the same name each:
struct TypeA {
typedef int subtype;
};
struct TypeB {
typedef float subtype;
};
and also types which don't have this sub-type but which are used in the same context:
struct TypeC {
// (no subtype defined)
};
How can I add a dummy sub-type which gives a custom compile error message?
My (so far unsuccessful) attempt is:
struct TypeC {
struct subtype {
static_assert(false, "Attempt to access the non-existent subtype of TypeC.");
};
};
But static_assert(false, ...)
can't work, as the compiler throws the error even if the type is never accessed.
How can I delay the evaluation of static_assert
to the time when the type is being accessed?
A failed attempt is to introduce a dummy enum and construct an expression out of it:
enum { X };
static_assert(X != X, "...");
Concrete use case: I have a class-template List
which is defined with the sub-types head
and tail
if non-empty, and should give an error if these sub-types are used if it is empty:
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;
};
If I simply leave out the types head
and tail
, when accessing e.g. the 3rd element of a list which has size 2 with the code List<int,int>::tail::tail::head
gives the not so nice message (g++ 4.7.2): 'head' is not a member of 'List<int>::tail {aka List<>}'
List<>
example doesn't complain about thestatic_assert
s? I thought the constant expression needed to involve a template parameter to avoid immediate evaluation. – Procambium