std :: less的编译时“相反”?

时间:2018-11-14 16:03:57

标签: c++ templates template-meta-programming

提前道歉。对于这个问题,我很难找到合适的措词...

作为练习,我正在处理一个固定大小的优先级队列,该队列将丢弃大于最大值的对象(对于查找X个最小对象的队列),并丢弃小于min的对象(对于持有最大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。这有道理吗?

**编辑**

尝试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中表达这种关系。

1 个答案:

答案 0 :(得分:2)

在原始类型上,!<>=之间没有明显的区别,因此您担心运行时成本是没有根据的。

C ++不是汇编语言。它描述了抽象机的行为。编译器将此映射到汇编,并且可以在汇编中以相同的方式实现没有明显差异的操作。

虽然需要一些经验来学习C ++中的“可观察”内容,但通常的规则是编写干净的代码,该代码在合理的情况下避免分配,保持da连续并且保持O标记速度正常,然后在测试程序之前检查性能问题。担心其他问题。

!<>=并不是“避免过早的悲观化”问题之一,因此,除非在性能分析时找到代码,否则您应该忽略它。