为什么std::queue允许冗余类型规范
Why std::queue allows redundant type specification?
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)的默认形参。
我的意思是,我不认为这是"好",在上面的声明例子中浮点规范被忽略;
像这样声明队列不是更类型安全吗?
更类型安全,是的,但不那么方便。queue
的普通用户并不关心底层容器,它实际上只是一个实现细节。它们只关心元素类型。这也是为了与其他容器类保持一致。
如果queue
类可以通过为容器指定一个类模板来使用就更好了,如下所示:
std::queue<int, std::list> myqueue;
从逻辑上讲,人们可能会期望这样的内容:
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 ...
额外的template参数阻止它工作。如果的第二个参数中添加了额外的参数queue
,则大多数用户定义容器不能使用;因为他们不会有第二个参数。当前的解决方案避免了这个问题(同时仍然允许客户端。代码来实例化std::queue<float>
,例如,没有(担心底层容器类型)
最后,为什么不呢?您的std::queue<float,
std::deque<std::string> >
示例可能无法编译,但是像std::queue<bool, std::vector<char> >
这样的东西是错误的(避免有问题的std::vector<bool>
)?只要…这两种方式都有隐含的转换,这取决于客户端以确保它能按他的意愿运作。(当然,实际上,这几乎不是个问题,因为客户机代码很少出现这种情况指定容器
如果您只关心防止"愚蠢"的情况,一个简单的完整性检查就足够了:
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中的类似功能
相关文章:
- 如何擦除冗余输入?
- 使用提升几何缓冲区缩放多边形时的冗余折点
- 我应该担心冗余声明吗?
- Qt的slot(?)将冗余命名空间插入连接
- 方法冗余移动调用的移动语义
- 使用 llvm 和本地值编号算法擦除冗余表达式
- 优化堆上创建的冗余变量
- 如何消除访客模式冗余?
- 表达式模板需要冗余重载
- C++,处理多个构造函数重载和冗余代码
- 使用模板基类消除工厂类派生类冗余的干净方法
- 连接两个文件时如何避免冗余尾随换行符?
- CMake:修改共享库时的冗余链接
- 提升精神 X3:"属性没有预期的大小"冗余
- 如何简化此冗余C++代码?
- 是``if`语句''在modulo之前和分配操作之前的冗余
- 使用最终类说明符时,最终函数说明符是否冗余?
- 联合类型定义中的冗余字节
- C++11 在特定情况下避免冗余返回类型
- 为什么std::queue允许冗余类型规范