Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > как сделать шаблон типа указателя на функцию?


Автор: victor79 25.7.2011, 21:06
т.е. что бы было что-то подобное:
Код

template<class T>
typedef void (*t_fn)( T val );

t_fn<int> abc;

void doint( int ii ) {
   printf("%i\n", ii);
}

int main() {
   abc = doint;
   abc(55);
}


Добавлено через 12 минут и 48 секунд
у меня объявлен шаблон с несколькими типами, и на эти несколько типов сделаны несколько переменных в нем, и на эти несколько переменных еще нужно привязать функции обработчики, которые устанавливаются в отдельные переменные, и если они не установлены то должны вызваться дефаултные обработчики. И между собой эти обработчики подобны по синтаксису - всякое копирование. И что бы не плодить множество определений обработчиков - и нужен такой шаблон.

Автор: mes 25.7.2011, 22:51
обернуть typedef в структуру..

Автор: victor79 26.7.2011, 03:33
Цитата(mes @  25.7.2011,  22:51 Найти цитируемый пост)
обернуть typedef в структуру.. 


сначала не подумал, что можно обернуть ТАКИМ образом. Придется при установке и вызове добираться через точку, но это уже гораздо проще.

Код

template<class T>
struct t_func {
     typedef void (*t_fn)(T val);
     t_fn fn;
};

t_func<int> abc;

void doint( int ii ) {
   printf("%i\n", ii);
}

int main() {
   abc.fn = doint;
   abc.fn(55);
}


Добавлено @ 03:35
возможно так даже лучше будет объединять в блоки функции. типа:
Код

class t_func {
    typedef ...
    typedef ...
    typedef ...
    t_fn_create  fn_create;
    t_fn_copy    fn_copy;
    t_fn_del      fn_del;
}


Автор: victor79 26.7.2011, 05:32
или еще вариант
Код

template<class T>
struct t_func {
   typedef void (*fn)(T val);
};

t_func<int>::fn abc;

void doint( int ii ) {
   printf("%i\n", ii);
}

int main() {
   abc = doint;
   abc(55);
}

Автор: afiskon 26.7.2011, 06:38
По-нормальному это делается через функтор, то есть объект с переопределенным operator(). Такие объекты помимо прочего можно использовать вместе с STL. Пример есть на вики.

Автор: EnergoHokum 26.7.2011, 13:27
http://www.cplusplus.com/reference/std/functional/pointer_to_unary_function/.

Автор: borisbn 26.7.2011, 14:10
EnergoHokum, единственный минус - нельзя обнулить (вернее межно, но потом никак не проверишь, что там 0).

Цитата(victor79 @  25.7.2011,  21:06 Найти цитируемый пост)
, и если они не установлены то должны вызваться дефаултные обработчики.

я понял под "не установлены" - равны 0

Автор: victor79 26.7.2011, 15:15
саму функцию я как раз то и не хочу заворачивать в структуру. Это лишние конструкции, которые уже не запаковать в библиотечные, и располагать их придется в основной структуре программы. Мне просто нужен тип типа ссылки на функцию и шаблонизированный. Это вроде как решил.

Вот если бы еще можно было делать статическими операторы определенные в структурах... Типа:
Код

struct t_fnspc {
    static int operator+( int a, int b) { /* do something */ };
};

int main() {
     int res = 5 t_fnspc::+ 10;
}

или другими способами определить диадические/монадические операторы с НАЗВАНИЕМ. Но это уже другой вопрос.

(на момент написания поста линку про функцию одного аргумента еще не увидел, нужно подумать про это свойство)

Автор: borisbn 26.7.2011, 15:20
Цитата(victor79 @  26.7.2011,  15:15 Найти цитируемый пост)
 int res = 5 t_fnspc::+ 10;

жесть. а чем operator() не устраивает ?
Код

struct t_fnspc {
    int operator()( int a, int b ) { return 0; }
};

int main() {
     int res = t_fnspc()( 5, 10 );
}

только лишними скобками ?

--------------------
уупс. afiskon уже говорил это... просмотрел

Автор: victor79 26.7.2011, 15:23
Цитата(borisbn @  26.7.2011,  15:20 Найти цитируемый пост)
жесть. а чем operator() не устраивает ?
Код

struct t_fnspc {
    int operator()( int a, int b ) { return 0; }
};
int main() {
     int res = t_fnspc()( 5, 10 );
}

только лишними скобками ? 

да в этом примере именно лишними скобками и не устраивает. Если выстраивать последовательности из 5-10 подряд операторов, то в скобках слишком путаешься.

Автор: bsa 26.7.2011, 15:36
victor79, вообще-то, так никто не делает. Обычно, делают так:
Код
struct t_fnspc {
    int operator()(int a, int b) { return 0; }
};
int main() {
     t_fnspc fnspc;
     int res = fnspc(5, 10);
}
Хотя, чаще используют в алгоритмах: 
Код
template<class InputIterator, class Functor>
void some_algorithm(InputIterator first, InputIterator last, Functor func)
{
   for(; first != last; ++first)
      *first = func(*first, 1234);
}
...
some_algorithm(container.begin(), container.end(), t_fnspc());

Автор: victor79 27.7.2011, 02:13
Цитата(EnergoHokum @  26.7.2011,  13:27 Найти цитируемый пост)
Указатель на функцию одного аргумента из STL. 

размышляя над примером оператора () пришел к выводу  smile , что это то же что и мой вариант t_fn<int>::fn, но там не нужно использовать в синтаксисе :: но будет вызываться конструктор - либо явный - дополнительная писанина, либо не явный - если автоконструирование - что мне не очень нравиться.

В общем мой вариант :: мне нравиться больше, по крайней мере пока не начну юзать STL.

Автор: EnergoHokum 27.7.2011, 06:51
Цитата

пока не начну юзать STL

С этим медлить не стоит. smile

Автор: bsa 27.7.2011, 15:04
Цитата(victor79 @  27.7.2011,  02:13 Найти цитируемый пост)
не явный - если автоконструирование - что мне не очень нравиться

Это почему еще? Для простых функторов вполне достаточно стандартного конструктора. А сложные иначе не сделаешь.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)