Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передача указателей на шаблонную функцию 
:(
    Опции темы
ANTON_AL
Дата 25.7.2007, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 292
Регистрация: 27.1.2007

Репутация: нет
Всего: нет



Доброго дня!

Есть некий набор шаблонных функций с одинаковым количеством шаблонных параметров:
Код

template< class T1, class T2 >
void FilterFunc1( T1 *pDataIn, T2 *pDataOut, int iOrder )
{

}


template< class T1, class T2, class iOrder >
void FilterFunc2( T1 *pDataIn, T2 *pDataOut, int iOrder )
{

}



Есть класс "Filter", который служит для запуска этих функций ( причём он не последний в иерархии классов ) и хранения промежуточных результатов. Ему в качестве шаблонного параметра должен передаваться указатель на какую либо функцию-фильтр.
Код

template< class FilterFunction >
class Filter
{
    public:
        Filter( ) { }

        template< class T1, class T2 >
        void Run( T1 *pDataIn, T2 *pDataOut, int iOrder ) { FilterFunction( pDataIn, pDataOut, iOrder ); }
};


Использоваться(внутри системы) это будет примерно так:
Код

    short *pSignal_In  = new short[SIGNAL_SIZE];
    int    *pSignal_Out = new int[SIGNAL_SIZE];

    
    Filter<FilterFunc1> SomeFilter1;
    SomeFilter1.Run( pSignal_In + 0,  pSignal_Out + 0,  SIGNAL_SIZE / 4 );
    SomeFilter1.Run( pSignal_In + 8,  pSignal_Out + 8,  SIGNAL_SIZE / 4 );
    SomeFilter1.Run( pSignal_In + 16, pSignal_Out + 16, SIGNAL_SIZE / 4 );
    SomeFilter1.Run( pSignal_In + 24, pSignal_Out + 24, SIGNAL_SIZE / 4 );

    Filter<FilterFunc2> SomeFilter2;
    SomeFilter2.Run( pSignal_In + 0,  pSignal_Out + 0,  SIGNAL_SIZE / 4 );
    SomeFilter2.Run( pSignal_In + 8,  pSignal_Out + 8,  SIGNAL_SIZE / 4 );
    SomeFilter2.Run( pSignal_In + 16, pSignal_Out + 16, SIGNAL_SIZE / 4 );
    SomeFilter2.Run( pSignal_In + 24, pSignal_Out + 24, SIGNAL_SIZE / 4 );



Т.е. пользователь может выбирать, какой функцией фильтровать сигнал.


Теперь всё вместе:
Код

#include <conio.h>
using namespace std;





template< class T1, class T2 >
void FilterFunc1( T1 *pDataIn, T2 *pDataOut, int iOrder )
{

}


template< class T1, class T2, class iOrder >
void FilterFunc2( T1 *pDataIn, T2 *pDataOut, int iOrder )
{

}


template< class FilterFunction >
class Filter
{
    public:
        Filter( ) { }

        template< class T1, class T2 >
        void Run( T1 *pDataIn, T2 *pDataOut, int iOrder ) { FilterFunction( pDataIn, pDataOut, iOrder ); }
};



#define SIGNAL_SIZE 32

void main( )
{
    short *pSignal_In  = new short[SIGNAL_SIZE];
    int    *pSignal_Out = new int[SIGNAL_SIZE];

    
    Filter<FilterFunc1> SomeFilter1;
    SomeFilter1.Run( pSignal_In + 0,  pSignal_Out + 0,  SIGNAL_SIZE / 4 );
    SomeFilter1.Run( pSignal_In + 8,  pSignal_Out + 8,  SIGNAL_SIZE / 4 );
    SomeFilter1.Run( pSignal_In + 16, pSignal_Out + 16, SIGNAL_SIZE / 4 );
    SomeFilter1.Run( pSignal_In + 24, pSignal_Out + 24, SIGNAL_SIZE / 4 );

    Filter<FilterFunc2> SomeFilter2;
    SomeFilter2.Run( pSignal_In + 0,  pSignal_Out + 0,  SIGNAL_SIZE / 4 );
    SomeFilter2.Run( pSignal_In + 8,  pSignal_Out + 8,  SIGNAL_SIZE / 4 );
    SomeFilter2.Run( pSignal_In + 16, pSignal_Out + 16, SIGNAL_SIZE / 4 );
    SomeFilter2.Run( pSignal_In + 24, pSignal_Out + 24, SIGNAL_SIZE / 4 );


    getch( );
}


Вопрос: как сформировать указатель на шаблонную функцию и передать его в класс Filter ??

Это сообщение отредактировал(а) ANTON_AL - 25.7.2007, 19:41
PM MAIL   Вверх
Xenon
Дата 25.7.2007, 19:42 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



Передача указателя на шаблонную фунцию?
Я думаю поймешь как к своему применить.
Код

template <typename TYPE> void func()
{
    std::cout << "Hello world from func " << typeid(TYPE).name();
}

class Filter
{
public:
    template <typename TYPE> void call(TYPE* pTr)
    {
        pTr();
    }
};

int main(int argc, char argv[]) 
{
    Filter obj;
    obj.call(func<double>);
    std::cin.get();
    return 0;
}


Это сообщение отредактировал(а) Xenon - 25.7.2007, 19:43


--------------------
user posted image  
PM MAIL   Вверх
Earnest
Дата 26.7.2007, 07:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Нельзя получить указатель на шаблонную функцию в прямом смысле этого слова (потому что ее нет в коде) - только на ее экземпляр, инстационированный с определенными параметрами. 
Т.е. если ты перейдешь от шаблона функции к указателю, ты потеряешь ее шаблонность (она будет работать только с конкретными типами).
В твоем случае лучше использовать функтор, а не функцию (т.е. объект с оператором () с той же сигнатурой). Лучше, потому что это полноценный тип, который может быть параметром шаблона. Тогда никаких проблем не ожидается.

Код

struct FilterFunc1
{
   template <class T1, class T2>
   void operator()(T1*, T2*) {... }
};


template <class FILTERFUNC>
class CFilter
{
   CFilter () {}
   
  // это на случай, если понадобятся какие-то параметры передать в фильтр
  // можно написать для 2, 3 и т.д. аргументов
   template <class PAR>
   CFilter (const PAR& p): m_p (p) {}


  // кстати, iOrder логичнее сделать параметром функции-фильтра, а не передавать
   template< class T1, class T2 >
    void Run( T1 *pDataIn, T2 *pDataOut) { m_f( pDataIn, pDataOut); }

private:
   FILTERFUNC m_f;
};


Вызов будет выглядеть именно так, как ты написал:

// другой функтор, с параметрами
struct FilterFunc2
{
   FilterFunc2 (LPARAM d): m_someData(d) {}

   template <class T1, class T2>
   void operator()(T1*, T2*) {... }

   LPARAM m_someData;
};

  CFilter<FilterFunc1> Filter1;
   ...

   CFilter <FilterFunc2> Filter2(someData);
   ...






--------------------
...
PM   Вверх
ANTON_AL
Дата 26.7.2007, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 292
Регистрация: 27.1.2007

Репутация: нет
Всего: нет



Спасибо, ребята, всё работает.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0935 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.