шаблоны
От: Аноним  
Дата: 15.03.06 10:32
Оценка:
Подскажите, как написать что-то такое

template< class T, T t >
T f()
{
  return t;
}

pfn = &f<3.3>();


Это можно реализовать, если два раза указать параметр шаблона. Но мне хочется указать параметр только один раз
Re: шаблоны
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 15.03.06 10:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Подскажите, как написать что-то такое


Для начала расскажи сценарий использования этой фичи.
Re[2]: шаблоны
От: Аноним  
Дата: 15.03.06 10:49
Оценка:
Здравствуйте, Alxndr, Вы писали:

A>Здравствуйте, Аноним, Вы писали:


А>>Подскажите, как написать что-то такое


A>Для начала расскажи сценарий использования этой фичи.


Сценарий приблизительно такой:



struct Callback
{
  void (*f1)( int p1, void * pCtx );
  void (*f2)( double p2, void * pCtx );
};

void mega_algo( Callback * pCallback, void * pCtx )
{
  ...
  pCallback->f1( 34, pCtx );
  ...
}

class C1
{
  void f()
  {
    Callback callback;
    callback.f1 = ...(cb_f1);  /*  вот тут что-то написать, что-бы вызов шел на C1::cb_f1()  */
    callback.f2 = ...(cb_f2);  /*  вот тут что-то написать, что-бы вызов шел на C1::cb_f2()  */
    mega_algo( &callback, this );
  }

  void cb_f1( int p1 );
  void cb_f2( double p2 );
};
Re[3]: шаблоны
От: remark Россия http://www.1024cores.net/
Дата: 15.03.06 11:05
Оценка:
Здравствуйте, Аноним, Вы писали:

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


A>>Здравствуйте, Аноним, Вы писали:


А>>>Подскажите, как написать что-то такое


A>>Для начала расскажи сценарий использования этой фичи.


А>Сценарий приблизительно такой:



А>

А>struct Callback
А>{
А>  void (*f1)( int p1, void * pCtx );
А>  void (*f2)( double p2, void * pCtx );
А>};

А>void mega_algo( Callback * pCallback, void * pCtx )
А>{
А>  ...
А>  pCallback->f1( 34, pCtx );
А>  ...
А>}

А>class C1
А>{
А>  void f()
А>  {
А>    Callback callback;
А>    callback.f1 = ...(cb_f1);  /*  вот тут что-то написать, что-бы вызов шел на C1::cb_f1()  */
А>    callback.f2 = ...(cb_f2);  /*  вот тут что-то написать, что-бы вызов шел на C1::cb_f2()  */
А>    mega_algo( &callback, this );
А>  }

А>  void cb_f1( int p1 );
А>  void cb_f2( double p2 );
А>};

А>



Не понятно, какое отношение это имеет к первому вопросу.
И как быть с void * pCtx? Сигнатуры функций не совпадают.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: шаблоны
От: Аноним  
Дата: 15.03.06 11:29
Оценка:
Здравствуйте, remark, Вы писали:
R>Не понятно, какое отношение это имеет к первому вопросу.
отношение не очевидное


R>И как быть с void * pCtx? Сигнатуры функций не совпадают.

void * pCtx должен превратится в this
идея в том чтоб шаблонами создавались функции вроде


void f1( int p1, void * pCtx )
{
  ((C1*)pCtx)->cb_f1( p1 );
}

вот мне лень писать эти функции, их могут буть десятки. Хочется написать один шаблон ( или что-то еще ).
Re[5]: шаблоны
От: remark Россия http://www.1024cores.net/
Дата: 15.03.06 12:11
Оценка:
Здравствуйте, Аноним, Вы писали:

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

R>>Не понятно, какое отношение это имеет к первому вопросу.
А>отношение не очевидное


R>>И как быть с void * pCtx? Сигнатуры функций не совпадают.

А>void * pCtx должен превратится в this
А>идея в том чтоб шаблонами создавались функции вроде


А>
А>void f1( int p1, void * pCtx )
А>{
А>  ((C1*)pCtx)->cb_f1( p1 );
А>}

А>

А>вот мне лень писать эти функции, их могут буть десятки. Хочется написать один шаблон ( или что-то еще ).


Лови:

template<typename ThisType, typename ParamType>
struct Wrapper
{
    typedef void (ThisType::*FuncType)(ParamType);
    template<FuncType func>
    static void call(ParamType param, void* ctx)
    {
        ThisType* self = reinterpret_cast<ThisType*>(ctx);
        FuncType f = func;
        (self->*f)(param);
    }
};


    callback.f1 = &Wrapper<C1, int>::call<&C1::cb_f1>;
    callback.f2 = &Wrapper<C1, double>::call<&C1::cb_f2>;




Синтаксис правда не очень короткий, но зато не надо писать обёртку для каждой функции.




1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[6]: шаблоны
От: Аноним  
Дата: 15.03.06 12:37
Оценка:
А покороче синтаксис нельзя?
Вроде есть какая-то "argument deduction" и если ее применить можно не писать int и double в аргуменрах шаблона — они будут дедуктится.

R>Лови:


R>
R>template<typename ThisType, typename ParamType>
R>struct Wrapper
R>{
R>    typedef void (ThisType::*FuncType)(ParamType);
R>    template<FuncType func>
R>    static void call(ParamType param, void* ctx)
R>    {
R>        ThisType* self = reinterpret_cast<ThisType*>(ctx);
R>        FuncType f = func;
R>        (self->*f)(param);
R>    }
R>};


R>    callback.f1 = &Wrapper<C1, int>::call<&C1::cb_f1>;
R>    callback.f2 = &Wrapper<C1, double>::call<&C1::cb_f2>;
R>




R>Синтаксис правда не очень короткий, но зато не надо писать обёртку для каждой функции.
Re[7]: шаблоны
От: remark Россия http://www.1024cores.net/
Дата: 15.03.06 12:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А покороче синтаксис нельзя?

А>Вроде есть какая-то "argument deduction" и если ее применить можно не писать int и double в аргуменрах шаблона — они будут дедуктится.

У меня у самого и была такая задумка изначально:


make_wrapper(&C1::cb_f1);



Но тут как-то сложно получается из-за указателей на функции-члены...



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[8]: шаблоны
От: remark Россия http://www.1024cores.net/
Дата: 15.03.06 12:43
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, Аноним, Вы писали:


А>>А покороче синтаксис нельзя?

А>>Вроде есть какая-то "argument deduction" и если ее применить можно не писать int и double в аргуменрах шаблона — они будут дедуктится.

R>У меня у самого и была такая задумка изначально:



R>
R>make_wrapper(&C1::cb_f1);
R>



R>Но тут как-то сложно получается из-за указателей на функции-члены...



Это нужно только для одного класса C1 или для многих?
Типов параметров (int, double) ограниченное количество или могут быть любые?


R>

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[9]: шаблоны
От: Аноним  
Дата: 15.03.06 13:08
Оценка:
R>Это нужно только для одного класса C1 или для многих?
R>Типов параметров (int, double) ограниченное количество или могут быть любые?

Ну, конечно, желетельно, для многих классов и для любых, но если есть решение при каких-то ограничениях — мне тоже будет интересно посмотреть.
Re[10]: шаблоны
От: night beast СССР  
Дата: 15.03.06 14:09
Оценка:
Здравствуйте, Аноним, Вы писали:


R>>Это нужно только для одного класса C1 или для многих?

R>>Типов параметров (int, double) ограниченное количество или могут быть любые?

А>Ну, конечно, желетельно, для многих классов и для любых, но если есть решение при каких-то ограничениях — мне тоже будет интересно посмотреть.



template< typename Function> 
struct wrapper;

template< typename Ret, class Class > 
struct wrapper< Ret (Class::*) () > 
{
    template< Ret (Class::*fn) () >
    Ret call ( void * ptr) {
        return ( static_cast<Class *> (ptr)->*(fn) ) (a);
    }
};

template< typename Ret, class Class, typename Arg1 > 
struct wrapper<Ret (Class::*) (Arg1)> 
{
    template< Ret (Class::*fn) (Arg1) >
    static Ret call ( Arg1 a, void * ptr) {
        return ( static_cast<Class *> (ptr)->*(fn) ) (a);
    }
};

... и далее пока руки не отвалятся


использовать wrapper<void (test::*)(int)>::call<&test::f1>

а еще лучше, взять boost::function и не мучаться
Re[10]: шаблоны
От: remark Россия http://www.1024cores.net/
Дата: 15.03.06 14:09
Оценка:
Здравствуйте, Аноним, Вы писали:


R>>Это нужно только для одного класса C1 или для многих?

R>>Типов параметров (int, double) ограниченное количество или могут быть любые?

А>Ну, конечно, желетельно, для многих классов и для любых, но если есть решение при каких-то ограничениях — мне тоже будет интересно посмотреть.



... всё же сложно получается...
Если есть возможность проще как-то переделать хранение калбек функций, чтобы без void* и что-бы всё было типобезопасное и на шаблонах



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: шаблоны
От: remark Россия http://www.1024cores.net/
Дата: 15.03.06 14:12
Оценка:
Здравствуйте, night beast, Вы писали:

NB>... и далее пока руки не отвалятся


Что бы руки не отваливались помогает boost.preprocessor — очень рекомендую


NB>использовать wrapper<void (test::*)(int)>::call<&test::f1>


В моём варианте и то проще использовать


NB>а еще лучше, взять boost::function и не мучаться


Согласен

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[12]: шаблоны
От: night beast СССР  
Дата: 15.03.06 15:07
Оценка:
Здравствуйте, remark, Вы писали:

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


NB>>... и далее пока руки не отвалятся


R>Что бы руки не отваливались помогает boost.preprocessor — очень рекомендую




NB>>использовать wrapper<void (test::*)(int)>::call<&test::f1>


R>В моём варианте и то проще использовать


твой вариант расчитан на один аргумент у функции, а здесь -- сколько влезет.
а если еще расширения подключить, то вот так

#define make_wrapper(fun) wrapper<typeof(fun)>::call<fun>
make_wrapper(&test::f1);



NB>>а еще лучше, взять boost::function и не мучаться


R>Согласен
Re[13]: шаблоны
От: remark Россия http://www.1024cores.net/
Дата: 15.03.06 15:20
Оценка:
Здравствуйте, night beast, Вы писали:

NB>твой вариант расчитан на один аргумент у функции, а здесь -- сколько влезет.

NB>а если еще расширения подключить, то вот так

NB>
NB>#define make_wrapper(fun) wrapper<typeof(fun)>::call<fun>
NB>make_wrapper(&test::f1);
NB>


А ну если так, то да


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[13]: шаблоны
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 16.03.06 01:43
Оценка: 10 (1) +1
Здравствуйте, night beast, Вы писали:

NB>а если еще расширения подключить, то вот так


NB>
NB>#define make_wrapper(fun) wrapper<typeof(fun)>::call<fun>
NB>make_wrapper(&test::f1);
NB>


Можно и без typeof обойтись:
template<class M>
struct member_function_traits;

template<class R, class T, class A0>
struct member_function_traits<R(T::*)(A0)>
{
    typedef R result_type;
    typedef T this_type;
    typedef A0 arg0_type;
};

template<class M>
struct adapter_traits
{
    typedef member_function_traits<M> traits_type;

    typedef typename traits_type::this_type this_type;
    typedef typename traits_type::arg0_type arg0_type;

    template<M m>
    static void adapter(arg0_type p, void *c) 
    {
        (reinterpret_cast<this_type*>(c)->*m)(p);
    }
};

template<class M>
adapter_traits<M> make_adapter_traits(M) { return adapter_traits<M>(); }

#define MAKE_ADAPTER(m) make_adapter_traits(m).adapter<m>;


Варианты использования:
// либо так (два раза указывать функцию):
callback.f1 = make_adapter_traits(&C1::cb_f1).adapter<&C1::cb_f1>;
callback.f2 = make_adapter_traits(&C1::cb_f2).adapter<&C1::cb_f2>;

// либо так
callback.f1 = MAKE_ADAPTER(&C1::cb_f1);
callback.f2 = MAKE_ADAPTER(&C1::cb_f2);
getboost.codeplex.com
citylizard.codeplex.com
Re[14]: шаблоны
От: night beast СССР  
Дата: 16.03.06 04:53
Оценка: +1
Здравствуйте, sergey_shandar, Вы писали:

_>Здравствуйте, night beast, Вы писали:


NB>>а если еще расширения подключить, то вот так


NB>>
NB>>#define make_wrapper(fun) wrapper<typeof(fun)>::call<fun>
NB>>make_wrapper(&test::f1);
NB>>


_>Можно и без typeof обойтись:


_>Варианты использования:

_>
_>// либо так (два раза указывать функцию):
_>callback.f1 = make_adapter_traits(&C1::cb_f1).adapter<&C1::cb_f1>;
_>callback.f2 = make_adapter_traits(&C1::cb_f2).adapter<&C1::cb_f2>;

_>// либо так
_>callback.f1 = MAKE_ADAPTER(&C1::cb_f1);
_>callback.f2 = MAKE_ADAPTER(&C1::cb_f2);
_>


это уже дома подумалось
только вместо make_adapter_traits(&C1::cb_f2).adapter<&C1::cb_f2>;
надо make_adapter_traits(&C1::cb_f2).instance<&C1::cb_f2>();,
которая возвращает adapter<&C1::cb_f2>.
без этого комо не компилирует...

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