Шаблоны, оверлоады и наследование - 2
От: IROV..  
Дата: 03.01.07 14:20
Оценка: 15 (4)
Хотелось бы вставить свои 5 копеек в этот пост, но поднимать из глубин както не хочется.

http://www.rsdn.ru/Forum/Message.aspx?mid=792643&only=1
Автор: Chez
Дата: 03.09.04


здесь идется речь о разруливании такой вот ситуации

template<class T>
inline void ASSERT_VALID(T* p) { ... }

inline void ASSERT_VALID(CObject* p) { ... }


* нашол эту тему чисто случайно, воспользовался поиском

Вот очень интерестное решение от 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 );
}


Конечно, это возможно не работает как то там по стандарту! но пока что збою не давала.

Юзаю в VisitorMask — для выборки типов.

Что скажите?
я не волшебник, я только учусь!
Re[7]: Шаблоны, оверлоады и наследование - 2
От: night beast СССР  
Дата: 05.01.07 11:35
Оценка: 1 (1)
Здравствуйте, IROV.., Вы писали:

IRO>ну тогда я вот так!!


IRO># define ASSERT_VALID( X ) ASSERT_VALID_IMPL( X, X )


тогда уж:
#define ASSERT_VALID( X ) ASSERT_VALID_IMPL( X, 0 ? X : 0 )

на случай если X имеет побочные эффекты.
Re[6]: Шаблоны, оверлоады и наследование - 2
От: IROV..  
Дата: 05.01.07 11:11
Оценка: :)
Здравствуйте, 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 )
я не волшебник, я только учусь!
Re: Шаблоны, оверлоады и наследование - 2
От: night beast СССР  
Дата: 04.01.07 05:36
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>template<class T>
IRO>inline void ASSERT_VALID(T* p) { ... }

IRO>inline void ASSERT_VALID(CObject* p) { ... }


IRO>* нашол эту тему чисто случайно, воспользовался поиском


IRO>Вот очень интерестное решение от MaximE.


IRO>Очень оригинально, красиво, но... я бы если честно не был рад такому вот коду.


а такому?
template<class T>
void ASSERT_VALID (T *, typename disable_base<T,CObject>::type * = 0);


IRO>Почему я поднял эту тему? потомучто месяц назат столкнулся именно с такой вот задачкой.

IRO>И вы знаете голову поломал очень хорошо. Но все же мое решение куда менее проще.

IRO>Конечно, это возможно не работает как то там по стандарту! но пока что збою не давала.


По стандарту работает.

IRO>Юзаю в VisitorMask — для выборки типов.


IRO>Что скажите?


немного усложним задачу:
template<class T> int ASSERT_VALID(T* p);
void ASSERT_VALID(CObject* p);


твой ход.
Re[2]: Шаблоны, оверлоады и наследование - 2
От: IROV..  
Дата: 04.01.07 18:39
Оценка:
Здравствуйте, night beast, Вы писали:

NB>а такому?

NB>
NB>template<class T>
NB>void ASSERT_VALID (T *, typename disable_base<T,CObject>::type * = 0);
NB>


Мне кажеться ты забыл одну из этих _сковородок_

template<class T>
struct disable_base
     : boost::mpl::if_<
           boost::mpl::or_<boost::is_base_and_derived<CObject, T>, boost::is_same<CObject, T> >
         , int&
         , int
         >
{};




NB>немного усложним задачу:

NB>
NB>template<class T> int ASSERT_VALID(T* p);
NB>void ASSERT_VALID(CObject* p);
NB>


NB>твой ход.


template<class T> int ASSERT_VALID(T* p);
void ASSERT_VALID_OBJECT_AND_NONE_RETURN(CObject* p);

я не волшебник, я только учусь!
Re: Шаблоны, оверлоады и наследование - 2
От: remark Россия http://www.1024cores.net/
Дата: 04.01.07 21:39
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Хотелось бы вставить свои 5 копеек в этот пост, но поднимать из глубин както не хочется.

IRO>http://www.rsdn.ru/Forum/Message.aspx?mid=792643&amp;only=1
Автор: Chez
Дата: 03.09.04

IRO>здесь идется речь о разруливании такой вот ситуации
IRO>Что скажите?


В исходном варианте одна функция была не шаблонная ...



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Шаблоны, оверлоады и наследование - 2
От: IROV..  
Дата: 04.01.07 22:06
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, IROV.., Вы писали:


IRO>>Хотелось бы вставить свои 5 копеек в этот пост, но поднимать из глубин както не хочется.

IRO>>http://www.rsdn.ru/Forum/Message.aspx?mid=792643&amp;only=1
Автор: Chez
Дата: 03.09.04

IRO>>здесь идется речь о разруливании такой вот ситуации
IRO>>Что скажите?


R>В исходном варианте одна функция была не шаблонная ...


ы?
я не волшебник, я только учусь!
Re[3]: Шаблоны, оверлоады и наследование - 2
От: remark Россия http://www.1024cores.net/
Дата: 04.01.07 23:07
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Здравствуйте, remark, Вы писали:


R>>Здравствуйте, IROV.., Вы писали:


IRO>>>Хотелось бы вставить свои 5 копеек в этот пост, но поднимать из глубин както не хочется.

IRO>>>http://www.rsdn.ru/Forum/Message.aspx?mid=792643&amp;only=1
Автор: Chez
Дата: 03.09.04

IRO>>>здесь идется речь о разруливании такой вот ситуации
IRO>>>Что скажите?


R>>В исходном варианте одна функция была не шаблонная ...


IRO>ы?


ASSERT_VALID(CObject* p) можно было в cpp файле определить. в твоём варианте — нельзя — шаблон


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Шаблоны, оверлоады и наследование - 2
От: IROV..  
Дата: 04.01.07 23:31
Оценка:
Здравствуйте, remark, Вы писали:

R>>>В исходном варианте одна функция была не шаблонная ...


IRO>>ы?


R>ASSERT_VALID(CObject* p) можно было в cpp файле определить. в твоём варианте — нельзя — шаблон


R>


void ASSERT_VALID_IMPL( CObject * _p, CObject * p )
{
    printf("Base\n");
}


лень уже проверять но кажется это проканает

я не волшебник, я только учусь!
Re[3]: Шаблоны, оверлоады и наследование - 2
От: night beast СССР  
Дата: 05.01.07 10:47
Оценка:
Здравствуйте, IROV.., Вы писали:

NB>>а такому?

NB>>
NB>>template<class T>
NB>>void ASSERT_VALID (T *, typename disable_base<T,CObject>::type * = 0);
NB>>


IRO>Мне кажеться ты забыл одну из этих _сковородок_


нет, я забыл другую вещь.
#include "my_utility.hpp"


мы же обсуждаем пользовательский код, правда?

IRO>


NB>>немного усложним задачу:

NB>>
NB>>template<class T> int ASSERT_VALID(T* p);
NB>>void ASSERT_VALID(CObject* p);
NB>>


NB>>твой ход.


IRO>
IRO>template<class T> int ASSERT_VALID(T* p);
IRO>void ASSERT_VALID_OBJECT_AND_NONE_RETURN(CObject* p);
IRO>

IRO>

или даже
template<class T> int ASSERT_VALID_TEMPLATE(T* p);
void ASSERT_VALID_OBJECT(CObject* p);




int и void взял просто для примера.
в действительности ситуация когда такие функции возвращают разные типы довольно часто встречается.
Re[4]: Шаблоны, оверлоады и наследование - 2
От: IROV..  
Дата: 05.01.07 10:55
Оценка:
Здравствуйте, night beast, Вы писали:

NB>Здравствуйте, IROV.., Вы писали:


NB>>>а такому?

NB>>>
NB>>>template<class T>
NB>>>void ASSERT_VALID (T *, typename disable_base<T,CObject>::type * = 0);
NB>>>


IRO>>Мне кажеться ты забыл одну из этих _сковородок_


NB>нет, я забыл другую вещь.

NB>
NB>#include "my_utility.hpp"
NB>


NB>мы же обсуждаем пользовательский код, правда?


Хм... меня еще волнует скорость компиляции

NB>или даже

NB>
NB>template<class T> int ASSERT_VALID_TEMPLATE(T* p);
NB>void ASSERT_VALID_OBJECT(CObject* p);
NB>


NB>


NB>int и void взял просто для примера.

NB>в действительности ситуация когда такие функции возвращают разные типы довольно часто встречается.

а как ты их собрался обрабатывать
я не волшебник, я только учусь!
Re[5]: Шаблоны, оверлоады и наследование - 2
От: night beast СССР  
Дата: 05.01.07 11:07
Оценка:
Здравствуйте, IROV.., Вы писали:

NB>>


NB>>int и void взял просто для примера.

NB>>в действительности ситуация когда такие функции возвращают разные типы довольно часто встречается.

IRO>а как ты их собрался обрабатывать


передавать в другую шаблоную функцию.
типичная ситуация для expression templates.
Re[8]: Шаблоны, оверлоады и наследование - 2
От: IROV..  
Дата: 05.01.07 11:51
Оценка:
Здравствуйте, night beast, Вы писали:

NB>Здравствуйте, IROV.., Вы писали:


IRO>>ну тогда я вот так!!


NB>
IRO>># define ASSERT_VALID( X ) ASSERT_VALID_IMPL( X, X )
NB>


NB>тогда уж:

NB>
NB>#define ASSERT_VALID( X ) ASSERT_VALID_IMPL( X, 0 ? X : 0 )
NB>

NB>на случай если X имеет побочные эффекты.

Согласен!!
я не волшебник, я только учусь!
Re[9]: Шаблоны, оверлоады и наследование - 2
От: night beast СССР  
Дата: 06.01.07 09:54
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO> Согласен!!


кстати, если нужда заставит откатиться к версии с 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> {}; // здесь убираем наследников.


собственно, все.

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.