如何在C ++中将略有不同的类型视为相同?

时间:2019-07-01 14:53:31

标签: c++

我有两个priority_queues-一个minheap和一个maxheap

priority_queue<int> maxheap;
priority_queue<int, vector<int>, greater<int>> minheap;

稍后在代码中,我需要从更大的堆中pop()

(maxheap.size() > minheap.size() ? maxheap : minheap).pop()

此行生成错误:

error: incompatible operand types ('priority_queue<[2 * ...], (default) std::less<int>>' and 'priority_queue<[2 * ...], greater<int>>')

显然,由于比较器的不同,maxheapminheap的类型也不同。

有没有解决的办法?显然,这两种类型是高度兼容的,因此将它们视为相同是非常有用的。

1 个答案:

答案 0 :(得分:11)

使用三元运算符要求两个对象都具有公共类型,这不是事实,因为您提到的两种类型不相关(既不是继承,也不是继承)。通过彼此转换)。

只需将代码更改为:

if (maxheap.size() > minheap.size())
{
    maxheap.pop();
}
else
{
    minheap.pop();
}

  

显然这两种类型是高度兼容的

这两种类型满足公开.pop()方法的简单概念,但是它们并不相关。

  

因此能够将它们视为相同是非常有用的

模板和概念可以为您提供帮助,但是对于行为像三元运算符的小模板并没有速记符号。您可以获得的最好的是:

pick(a, b, [](const auto& a, const auto& b)
{
    return a.size() > b.size();
},
[](auto&& x)
{
    x.pop()
});

pick类似(粗糙,需要转发且未经测试):

template <typename A, typename B, typename Predicate, typename F>
void pick(A&& a, B&& b, Predicate&& predicate, F&& f)
{
    if (predicate(a, b))
    {
        f(a);
    }
    else 
    {
        f(b);
    }
}

但是样板的数量无法达到目的。