Извиняюсь заранее.У меня возникают трудности с поиском правильной формулировки для этого вопроса ...
В качестве упражнения я работаю над очередью с фиксированным приоритетом, которая выбрасывает объекты, превышающие максимальное значение (дляочередь, находящая самый маленький объект X) и выбрасывает объекты меньше чем мин (для очереди, содержащей самые большие объекты X).Вопрос в том, существует ли способ достижения логической «противоположности» компаратора во время компиляции.
См. Закомментированную строку в коде ниже:
template <
typename T,
typename Container = std::vector<T>,
typename Compare = std::less<typename Container::value_type>>
class fixed_size_priority_queue : public std::priority_queue<T, Container, Compare>
{
typename Container::size_type maxSize;
using base = std::priority_queue<T, Container, Compare>;
public:
fixed_size_priority_queue(std::size_t size) : base(), maxSize(size)
{
base::c.reserve(size);
}
void push(T value)
{
if (base::size() < maxSize)
{
base::push(value);
}
// is there some way of arriving at compile-time opposite of 'comp'?
else if (!base::comp(base::top(), value))
{
while (base::size() >= maxSize)
{
base::pop();
}
base::push(value);
}
}
};
void test_fixedPriQueue()
{
using smallestInts = fixed_size_priority_queue<int>;
smallestInts fq(4);
fq.push(5);
fq.push(3);
fq.push(5);
fq.push(5);
fq.push(7);
fq.push(11);
fq.push(1);
fq.push(2);
}
int main(int argc, char const *argv[])
{
test_fixedPriQueue();
return 0;
}
Я простоиспользовал оператор not (!), чтобы выполнить работу, но повлечет ли это за собой, хотя и очень маленькие, затраты времени выполнения?Есть ли способ достичь std::greater_equal
, когда мой класс использует Compare = std::less
?
Я надеялся использовать что-то вроде std::not<Compare>
, которое разрешило бы до std::greater_equal
, когда параметр шаблона Compare
равен std::less
.Имеет ли это смысл?
** edit **
Попытка предложения от sergeyA дала то, что я искал:
template<typename T, typename Comparison>
struct logical_opposite
{
using op = void;
};
template <typename T>
struct logical_opposite<T, std::less<T>>
{
using op = std::greater_equal<T>;
};
template <typename T>
struct logical_opposite<T, std::greater<T>>
{
using op = std::less_equal<T>;
};
Затем в классе, полученном из priority_queue, создайте экземпляр объекта с логической противоположностью и используйте его при добавлении в очередь:
//...
typename logical_opposite<T, Compare>::op not_comp;
public:
fixed_size_priority_queue(std::size_t size) : base(), maxSize(size), not_comp()
//....
Между типами функторов сравнения существует логическая связь, и я надеялся, что эта связь была выражена в STL.