Использование указателя на функцию в качестве параметра шаблона - PullRequest
0 голосов
/ 22 октября 2010

(C ++) Я получил несколько классов Entry и получил интерфейс BaseProcessor, который инкапсулирует логику обработки Entry.(см. код ниже)

Запись не предоставляет оператора <().BaseProcessor предоставляет указатель на функцию less (Entry, Entry), которая специфична для конкретной реализации BaseProcessor. </p>

Я могу использовать указатель функции для сравнения экземпляров Entry в моей программе.Однако мне нужно создать std :: set (или std :: map, или что-то еще, что использует less ()) для класса Entry.Я пытался использовать производный класс std :: binary_function, чтобы передать его в std :: set, но похоже, что я не могу передать значение указателя функции в шаблон.

Как я могу это сделать?Возможно ли это с C ++ 03?

Спасибо.

struct Entry
{
  // ...
private: 
  bool operator< (const Entry &) const; // Should be defined by BaseProcessor.
};

typedef bool (*LessFunc)(const Entry &, const Entry &);

class BaseProcessor
{
public:
  // ...
  virtual LessFunc getLessFunc () const = 0;
};

// ...

BaseProcessor *processor = getProcessor();
LessFunc lessfunc = processor->getLessFunc();

Entry e1;
Entry e2;
bool isLess = lessfunc(e1, e2);  // OK

typedef std::set<Entry, ???> EntrySetImpl; // how to use lessfunc here?
EntrySetImpl entries;   

1 Ответ

5 голосов
/ 22 октября 2010

Вы пробовали это?

typedef std::set<Entry, LessFunc> EntrySetImpl;
EntrySetImpl entries(lessfunc);

Обратите внимание, что вам нужно указать тип вашей функции сравнения или объекта в качестве параметра шаблона для set, а затем передать его экземпляр функции сравнения или объекта, когда вы на самом деле создаете набор.


Я отредактирую свой ответ, чтобы ответить на ваш дополнительный вопрос, потому что это немного проще.

Вы можете определить шаблон следующим образом:

template <LessFunc func> class MyContainer { /*code*/ };

Однако выгода заключается в том, что вы должны указать специфическую функцию, а не переменную-указатель функции, так какаргумент шаблона.Так, например, это нормально:

bool CompareEntries1(const Entry &, const Entry &);
MyContainer<CompareEntries1> container;

... но это не так:

bool CompareEntries1(const Entry &, const Entry &);
LessFunc lessfunc = &CompareEntries1; //or any other way of getting a LessFunc
MyContainer<lessfunc> container;

Если вы использовали классы шаблонов массива, такие как boost::array,вы могли видеть что-то подобное раньше.Вы можете написать array<int, 10>, чтобы объявить массив из 10 элементов, но вы не можете, например, написать array<int, abs(x)>.Размер массива должен быть таким, что компилятор может сказать во время компиляции программы, но до его запуска.(Существует очень специфический набор правил о том, что разрешено - даже если кажется, что компилятор должен быть в состоянии определить аргумент шаблона, как в примере LessFunc выше, он все равно должен следовать определенным правилам.В случае аргументов шаблона указателя на функцию аргумент должен быть именем функции или &, за которым следует имя функции.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...