|
Boost Users : |
Subject: Re: [Boost-users] [MPL] implementing a "trait"?
From: Wouter van Ooijen (wouter_at_[hidden])
Date: 2014-02-04 13:52:19
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
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net