为什么std :: queue允许冗余类型规范?

时间:2011-04-18 10:10:24

标签: c++ templates stl containers

STL库类std :: queue的前向声明如下:

namespace std {
    template<typename T, class container = deque<T>> class queue
}

这意味着我们可以使用不同的类型规范来声明类型为queue的对象:

std::queue<float, std::deque<std::string>> string_queue;

为什么这是可能的?如此声明队列不是更安全的类型:

template<class implementation>
class queue_base
{
private:
    implementation m_impl;
    /* ----------------------------------------------------------- */

public:
    typedef implementation                      container_type;
    typedef typename implementation::size_type  size_type;
    typedef queue_base<implementation>          this_type;
    typedef typename implementation::value_type value_type;
    /* ----------------------------------------------------------- */

    queue_base         ();
    queue_base         (queue_base const& other);
    explicit queue_base(container_type const& other);
    /* ----------------------------------------------------------- */

    value_type&       back ();
    value_type const& back () const;
    bool              empty() const;
    value_type&       front();
    value_type const& front() const;
    void              pop  ();
    void              push (value_type const& value);
    size_type         size () const;
    /* ----------------------------------------------------------- */
}; /* template<class> class queue_base */
/* --------------------------------------------------------------- */

std :: queue的大多数实现我已经看到实现'value_type'和'size_type'的方式与我在上面的代码中看到的相同。因此,模板参数'T'仅用于模板参数'container'(std :: deque)的默认参数。

我的意思是,我认为上面的声明示例中的float规范被忽略并不“很好”;无论它是否有效。

3 个答案:

答案 0 :(得分:2)

  

如此声明队列不是更安全的类型:

更多类型安全是的,但不方便。 queue的普通用户不关心底层容器,它实际上只是一个实现细节。他们只关心元素类型。这也是为了与其他容器类保持一致。

如果通过为容器指定类模板可以使queue类可用,那就更好了,如下所示:

std::queue<int, std::list> myqueue;

但遗憾的是,在C ++中没有好的,可移植的方法。

答案 1 :(得分:1)

如果你只关心防止“愚蠢”的情况,那么简单的完整性检查就足够了:

template <typename T, typename Container>
class queue
{
  static_assert(std::is_same<T, typename Container::value_type>::value,
    "queue require T and Container::value_type to be identical");
};

C ++ 03中的类似工具。

答案 2 :(得分:0)

从逻辑上讲,人们可能会想到这样的事情:

template<typename T, template<typenameU> class C = std::deque>
class queue
{
protected:
    C<T> c;
public:
    //  ...
};

问题是std::deque与模板不匹配 论证,因为它实际上是:

template<typename T, typename Allocator = allocator<T> >
class deque ...

额外的模板参数阻止它工作。而如果 额外的参数被添加到第二个参数 queue,然后无法使用大多数用户定义的容器, 因为他们没有第二个论点。目前 解决方案回避了这个问题(同时仍然允许客户端 用于实例化std::queue<float>的代码,例如,没有 担心底层容器类型。)

最后,为什么不呢?您的std::queue<float, std::deque<std::string> >示例可能无法编译,但是什么是 std::queue<bool, std::vector<char> >之类的错误 (避免有问题的std::vector<bool>)?只要 两种方式都有隐含的转换,取决于客户端 确保它做到他想要的。 (当然,在实践中, 它几乎从来不是一个问题,因为它很少用于客户端代码 指定容器。)