如何编写可以接受堆栈或队列的函数模板?
我正在实现四种算法,除了使用的数据结构外,它们完全相同 - 两种使用 priority_queue
,一种使用 stack
,最后一种使用 priority_queue
使用队列
。它们相对较长,所以我只想有一个函数模板,它接受容器类型作为模板参数,然后让每个算法使用适当的参数调用该模板,如下所示:
template <class Container>
void foo(/* args */)
{
Container dataStructure;
// Algorithm goes here
}
void queueBased(/* args */)
{
foo<queue<Item> >(/* args */);
}
void stackBased(/* args */)
{
foo<stack<Item> >(/* args */);
}
我已经设法做到了这一点使用基于 priority_queue
和 stack
的实现,但我无法对基于 queue
的算法执行相同的操作,因为它使用不同的访问最前面元素的名称(front( )
而不是 top( )
)。我知道我可以专门针对这种情况使用模板,但是这样我就会有大量重复的代码(这是我试图避免的)。
实现这一目标的最佳方法是什么?我的第一直觉是为队列创建一个包装类,添加一个与 stack
等价的 top( )
操作,但我一直在读到子类化 STL 类是一个不不。那么我应该如何获得这种行为呢?
I'm implementing four algorithms that are completely identical except for what data structure they use — two use priority_queue
, one uses stack
, and the last uses queue
. They're relatively long, so I'd like to have just one function template that accepts the container type as a template argument and then have each algorithm call that template with the appropriate argument, like so:
template <class Container>
void foo(/* args */)
{
Container dataStructure;
// Algorithm goes here
}
void queueBased(/* args */)
{
foo<queue<Item> >(/* args */);
}
void stackBased(/* args */)
{
foo<stack<Item> >(/* args */);
}
I've managed to do just this with the priority_queue
- and stack
-based implementations, but I can't do the same for the queue
-based algorithm because it uses a different name to access the foremost element (front( )
instead of top( )
). I know that I could specialize the template for this case, but then I'd have a big stretch of duplicated code (which is what I'm trying to avoid).
What's the best way to accomplish this? My first instinct was to create a wrapper class for queue that adds a top( )
operation equivalent to stack
's, but I've been reading that subclassing STL classes is a no-no. How should I get this behavior, then?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以编写一个在容器适配器类型上重载的非成员
top
函数:如果您实际上将不同的序列容器与容器适配器一起使用(通过其
Sequence
模板参数) ),您需要适当修改重载来处理该问题。直接使用序列容器(例如std::vector)可能比使用序列适配器之一更直接。
You can write a non-member
top
function overloaded on the type of the container adapter:If you actually use a different sequence container with the container adapters (via their
Sequence
template parameter), you'll need to modify the overloads appropriately to handle that.It might just be more straightforward to use a sequence container (e.g.
std::vector
) directly rather than using one of the sequence adapters.您可以使用部分专业化来选择正确的方法:
You can use partial specialization to select the right method:
您可以在不使用继承的情况下创建一个围绕 std::queue 的包装器;事实上,继承在这里是错误的工具,因为您试图装饰一个
队列
,而不是精炼或扩展 队列。这是一种可能的实现:希望这有帮助!
You can create a wrapper around
std::queue
without using inheritance; in fact, inheritance would be the wrong tool here because you're trying to decorate aqueue
rather than refining or extending thequeue
. Here's one possible implementation:Hope this helps!
queue
、priority_queue
和stack
都是容器适配器;它们是底层容器的包装器(默认情况下,queue
为deque
,stack
和vector
优先级队列)。由于
vector
、deque
和list
(“真正的”容器类)共享它们的大部分方法,因此您可以省略中间人并使用这些方法类代替。请记住,公共继承对于 STL 容器来说并不是一个好主意; 私有继承是可以的(可能也是你想要的)。
queue
,priority_queue
andstack
are all container adaptors; they are wrappers around an underlying container (by default,deque
forqueue
andstack
andvector
forpriority_queue
).Since
vector
,deque
andlist
(the "real" container classes) share most of their methods, you could cut the middle man and use those classes instead.And keep in mind that public inheritance is not a good idea for STL containers; private inheritance is okay (and probably what you want).
front()
和top()
特定于某些类型的容器,但所有 STL 容器都支持*begin()
。front()
andtop()
are specific to certain types of containers, but all STL containers support*begin()
.