URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9461
[ Назад ]

Исходное сообщение
"template class predicate"

Отправлено handler2006 , 19-Май-12 19:13 
Здравствуйте!
Мне нужно создать шаблон класса, в котором в качестве параметра шаблона выступает функция.
Например:


int f(int i) {return i*i;}

template<class T>
class A
{
typedef T int(p*)(int);
p func;
int x;
public:
  A() {x = *p(2);}
};

A<&f> a

Как это правильно называется и где можно почитать описание?
Спасибо.
Алексей


Содержание

Сообщения в этом обсуждении
"template class predicate"
Отправлено elvenic , 20-Май-12 01:40 
 
#include <iostream>

struct IntSquarer { int operator()(int i) {return i*i;} };
struct IntTripler { int operator()(int i) { return (3 * i); } };


template<typename Functor>
class A
{
  int x;
  Functor funct;
public:
  A() { x = funct(2);}
  int getX() { return x; }
};

int main(int argc, char *argv[])
{
  A<IntSquarer> squarer;
  std::cout << "squarer.getX(): [" << squarer.getX() << "]\n";

  A<IntTripler> tripler;
  std::cout << "tripler.getX(): [" << tripler.getX() << "]\n";

}

Это компилится и печатает:


squarer.getX(): [4]
tripler.getX(): [6]

Тут идея в том что вместо простой функции вы создаете функторы - т.е. классы (или в данном примере, struct'ы) с определенным 'operator()'; и в коде этого оператора вы пишете то что вы хотели написать в коде простой функции. Поскольку вы определили не просто функцию, а класс, т.е.'тип', этот тип может быть параметером темплейта, и темплейтный класс может создать об'ект типа этого параметра, и поскольку предполагается что он функтор, его можно 'вызвать' как функцию (x = funct(2)).  


"template class predicate"
Отправлено handler2006 , 20-Май-12 07:02 
Спасибо, хороший пример.
А по-проще, чтобы просто функцию как параметр шаблона класса можно было передать?

"template class predicate"
Отправлено elvenic , 20-Май-12 08:40 
> Спасибо, хороший пример.
> А по-проще, чтобы просто функцию как параметр шаблона класса можно было передать?

Хм, оказывается можно и так:

 
#include <iostream>

typedef int (*MyFunPtrType)(int);

template<MyFunPtrType fptrParam>
class A
{
  int x;
  MyFunPtrType fptr;
public:
  A() : fptr(fptrParam) { x = fptr(2);}
  int getX() { return x; }
};


int intQuadruple(int i) { return 4 * i; };

int main(int argc, char *argv[])
{
  A<intQuadruple> quadrupler;
  std::cout << "quadrupler.getX(): [" << quadrupler.getX() << "]\n";
}

Это компилится и печатает:


quadrupler.getX(): [8]

Тут надо было догадаться что fptr, который является не типом, а членом класса, нужно инициализировать в конструкторе (A() : fptr(fptrParam) ... ), а значение которым он инициализируется как раз и передается как не-типовий параметр темплейта (template<MyFunPtrType fptrParam>) :)