* нашол эту тему чисто случайно, воспользовался поиском
Вот очень интерестное решение от MaximE.
template<class T>
inline// запретим использовать этот шаблон для CObject* и его наследниковtypename boost::disable_if<boost::mpl::or_<boost::is_base_and_derived<CObject, T>, boost::is_same<CObject, T> >, void>::type
void ASSERT_VALID(T* p) { ... }
Очень оригинально, красиво, но... я бы если честно не был рад такому вот коду.
Почему я поднял эту тему? потомучто месяц назат столкнулся именно с такой вот задачкой.
И вы знаете голову поломал очень хорошо. Но все же мое решение куда менее проще.
template<class T>
void ASSERT_VALID_IMPL( T * p, ... )
{
printf("Other\n");
}
template<class T>
void ASSERT_VALID_IMPL( T * _p, CObject * p )
{
printf("Base\n");
}
template<class T>
void ASSERT_VALID( T * p )
{
ASSERT_VALID_IMPL( p , p );
}
Конечно, это возможно не работает как то там по стандарту! но пока что збою не давала.
IRO>* нашол эту тему чисто случайно, воспользовался поиском
IRO>Вот очень интерестное решение от MaximE.
IRO>Очень оригинально, красиво, но... я бы если честно не был рад такому вот коду.
IRO>Почему я поднял эту тему? потомучто месяц назат столкнулся именно с такой вот задачкой. IRO>И вы знаете голову поломал очень хорошо. Но все же мое решение куда менее проще.
IRO>Конечно, это возможно не работает как то там по стандарту! но пока что збою не давала.
По стандарту работает.
IRO>Юзаю в VisitorMask — для выборки типов.
IRO>Что скажите?
немного усложним задачу:
template<class T> int ASSERT_VALID(T* p);
void ASSERT_VALID(CObject* p);
Здравствуйте, IROV.., Вы писали:
IRO>Здравствуйте, remark, Вы писали:
R>>Здравствуйте, IROV.., Вы писали:
IRO>>>Хотелось бы вставить свои 5 копеек в этот пост, но поднимать из глубин както не хочется. IRO>>>http://www.rsdn.ru/Forum/Message.aspx?mid=792643&only=1
Здравствуйте, remark, Вы писали:
R>>>В исходном варианте одна функция была не шаблонная ...
IRO>>ы?
R>ASSERT_VALID(CObject* p) можно было в cpp файле определить. в твоём варианте — нельзя — шаблон
R>
Здравствуйте, IROV.., Вы писали:
NB>>
NB>>int и void взял просто для примера. NB>>в действительности ситуация когда такие функции возвращают разные типы довольно часто встречается.
IRO>а как ты их собрался обрабатывать
передавать в другую шаблоную функцию.
типичная ситуация для expression templates.
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, IROV.., Вы писали:
NB>>>
NB>>>int и void взял просто для примера. NB>>>в действительности ситуация когда такие функции возвращают разные типы довольно часто встречается.
IRO>>а как ты их собрался обрабатывать
NB>передавать в другую шаблоную функцию. NB>типичная ситуация для expression templates.
ну тогда я вот так!!
template<class T>
void ASSERT_VALID_IMPL( T * p, ... )
{
printf("Other\n");
}
int ASSERT_VALID_IMPL( CObject * p, CObject * p )
{
printf("Base\n");
}
# define ASSERT_VALID( X ) ASSERT_VALID_IMPL( X, X )
кстати, если нужда заставит откатиться к версии с disable_base, то его достаточно просто реализовать без буста.
как определять наследование ты уже знаешь, осталось вынести это в отдельный клас.
template< class B, class D >
struct is_base_of
{
static char (& test ( B * ) ) [2];
static char (& test ( ... ) ) [1]; // и почему sizeof (void) != 0 ? приходится извращиться.static const int value = sizeof ( test ( (D*) 0 ) ) - 1;
};
template< class B, class D, int where = is_base_of<B,D>::value >
struct disable_base { typedef D type; };
template< class B, class D > struct disable_base<B,D,1> {}; // здесь убираем наследников.