У меня есть набор данных, который должен быть отсортирован по критериям, определяемым пользователем во время выполнения.
В идеале этот критерий сортировки должен передаваться как параметр в функции, такой как:
void mainFunction(
InputData const &inputData,
OutputData &outputData,
BaseSortingCriteria const &compareFunctor)
{
/* The data is sorted by this map using the custom provided functor as criteria */
std::map<InputDataType, ValueType, BaseSortingCriteria> sortedSets(compareFunctor);
...
}
Чтобы получить это, я создал виртуальный функтор, представляющий базовые критерии, такие как:
struct VirtualSortingCriteria
{
virtual bool operator()(
const InputDataType &var1,
const InputDataType &var2) const = 0;
}
И чтобы сохранить общий интерфейс, базовый функтор, который простовыполняет «настоящий» функтор, переданный во время построения:
struct BaseSortingCriteria
{
BaseSortingCriteria(
std::shared_ptr<const VirtualSortingCriteria> pCompareFunctor) :
m_realCompareFunctor(pCompareFunctor)
{
}
bool operator()(
const InputDataType &var1,
const InputDataType &var2)
{
return m_realCompareFunctor->operator()(var1, var2);
}
private:
/** Pointer to the real functor to be used. */
std::shared_ptr<const VirtualSortingCriteria> const m_realCompareFunctor;
}
И я определил пару «настоящих» функторов для проверки:
struct RealFunctorVersionA final : public VirtualSortingCriteria
{
bool operator () (
InputDataType const &var1,
InputDataType const &var2) const;
};
struct RealFunctorVersionB final : public VirtualSortingCriteria
{
bool operator () (
InputDataType const &var1,
InputDataType const &var2) const;
};
Код, который на самом деле использует эти разныеКритерии сортировки выглядят так:
std::shared_ptr<VirtualSortingCriteria> cmpFunctor;
switch(userSelectedSortingCriteria)
{
case CRITERIA_A:
cmpFunctor.reset(new RealFunctorVersionA);
break;
case CRITERIA_B:
cmpFunctor.reset(new RealFunctorVersionB);
break;
default:
break;
}
BaseSortingCriteria baseCmpFunctor(cmpFunctor);
mainFunction(inputData, outputData, baseCmpFunctor);
Все это прекрасно работает. Тем не менее, я думаю, что это слишком сложно, чтобы достичь того, что я хочу, плюс у меня есть ощущение, что необходимость использовать функцию полиморфизма подразумевает, что «настоящие» функторы больше не могут быть встроены, что приводит к вероятности (хотя я еще не измерял) снижение производительности.
Я не уверен, что это можно было бы проще исправить с помощью шаблонов (поскольку выбор функтора выполняется во время выполнения).
Есть предложения? Или я просто обдумываю проблему, и это приемлемое решение? Как насчет производительности?
Я не использую простые функции в стиле C (bool (*)(InputDataType const &var1, InputDataType const &var2))
в интерфейсе mainFunction()
, чтобы иметь возможность доступа к дополнительным функциям, предоставляемым функторами, таким как состояние, параметры построения и т. Д.
Заранее большое спасибо за совет.