John M. Dlugosz schreef op 04-Feb-14 7:03 PM:
I want to mark certain types as being of a category of my invention (e.g. is_pretty), for purposes of using enable_if in the same manner is standard type traits such as is_arithmetic etc.
The trait will be false by default, and I'd declare something to nominate types that should be seen to have that trait. I want it to follow inheritance; if B has been declared to be in my category, and C is derived from B, then C will also be in that category without needing to do anything more (though some way to turn it _off_ would be available).
I use typedef void has_some_interface; inside the class to identify that a class implements some interface. I could write out a global test template and specialization to do facilitate the checking, but I prefer the macro #define ASSERT_PROVIDES_INTERFACE( T, V ) \ template< class t, class x = void > struct V \ { static constexpr bool value = false; }; \ template< class t > struct V< t, typename t::V > \ { static constexpr bool value = true; }; \ static_assert( \ V< T >::value, \ "the " #T " template argument doesn't provide " #V \ ); (the \'s line up in a non-proporitionally font) which writes them 'locally'. Use it like this: struct implements_some_interface { typedef void has_some_interface; . . . }; template< class t > class uses_some_interface { ASSERT_PROVIDES_INTERFACE( t, some_interface ); . . . }; The error message issued by GCC when the feature id type is not provided is reasonably close to the top of the error list. In practice I write the identification type in an 'archetype' class that serves to identify the interface elements that an real implementation must provide (sort of an abstract base class, but for compile-time inheritance): struct char_out_channel_archetype { typedef void has_char_out_channel; static void put( char c ); }; struct char_in_channel_archetype { typedef void has_char_in_channel; static char get( ); }; struct uart : public char_out_channel_archetype, public char_in_channel_archetype { static void put( char c ){ . . . } static char get(){ . . . } }; A pity that I can't use 'override' to make sure that the implementations realy override a declaration in a base class, that works only for non-static methods. (WHY??) Wouter van Ooijen