是否有访问的基础容器的标准方式stack
, queue
, priority_queue
?
我发现了一个叫方法: _Get_container()
在VS2008
实现stack
和queue
,但没有一个priority_queue
! 我认为这是不规范的反正。
另外,我知道这是一个愚蠢的问题! 我在哪里可以找到标准库的官方文件?
只是为了澄清,我是不是要乱用下面的容器。 所有我试图做的是这样的:
template <class Container>
std::ostream& printOneValueContainer(std::ostream& outputstream, Container& container)
{
Container::const_iterator beg = container.begin();
outputstream << "[";
while(beg != container.end())
{
outputstream << " " << *beg++;
}
outputstream << " ]";
return outputstream;
}
// stack, queue
template
< class Type
, template<class Type, class Container = std::deque<Type> > class Adapter
>
std::ostream& operator<<(std::ostream& outputstream, const Adapter<Type>& adapter)
{
return printOneValueContainer(outputstream, adapter._Get_container());
}
.
.
.
std::stack<int> iStack;
.
.
std::cout << iStack << std::endl;
我希望你能看到_Get_container()
不规范,而且没有一个priority_queue
在VS2008
的实现。
Answer 1:
我发现某处以下解决方案在网络上,我用它在我的项目:
template <class T, class S, class C>
S& Container(priority_queue<T, S, C>& q) {
struct HackedQueue : private priority_queue<T, S, C> {
static S& Container(priority_queue<T, S, C>& q) {
return q.*&HackedQueue::c;
}
};
return HackedQueue::Container(q);
}
int main()
{
priority_queue<SomeClass> pq;
vector<SomeClass> &tasks = Container(pq);
return 0;
}
玩得开心 :)。
Answer 2:
我的评论中提到,但经过一番思考这似乎是一个确定的解决方案。 queue
/ stack
/ priority_queue
(即,所有的适配器类的)都有一个protected
成员c
这是基础容器(见ISO / IEC 14882:2003节23.2.2.4),所以如果你从任何这些继承时,可以直接访问它。
我知道的智慧,典型的是不因非虚拟dtors STL容器继承,但这种情况是个例外。 我们的目标是不超载的功能,但作出轻微扩展适配器的接口。 下面是添加到访问底层容器的能力的例子。
#include <queue>
#include <iostream>
template <class Container>
class Adapter : public Container {
public:
typedef typename Container::container_type container_type;
container_type &get_container() { return this->c; }
};
int main() {
typedef std::queue<int> C;
typedef Adapter<C> Container;
Container adapter;
for(int i = 0; i < 10; ++i) {
adapter.push(i);
}
Container::container_type &c = adapter.get_container();
for(Container::container_type::iterator it = c.begin(); it != c.end(); ++it) {
std::cout << *it << std::endl;
}
}
不幸的是,你将不得不求助于型双关语“升级”现有std::queue<int> *
的Adapter<std::queue<int> > *
没有双关类型。 从技术上讲,这可能会很好地工作......但我建议反对:
typedef std::stack<int> C;
typedef Adapter<C> Container;
C stack;
// put stuff in stack
Container *adapter = reinterpret_cast<Container *>(&stack);
Container::container_type &c = adapter->get_container();
// from here, same as above
因此,我建议使用类型定义,可以很容易在两者之间切换。 (另外,在我的例子注意到,你只需要改变1号线将其从一个更改queue
的stack
,因为自由使用的typedef
为s)。
Answer 3:
根据该接受的答案 ,一个更通用的方法:
template <class ADAPTER>
typename ADAPTER::container_type & get_container (ADAPTER &a)
{
struct hack : ADAPTER {
static typename ADAPTER::container_type & get (ADAPTER &a) {
return a.*&hack::c;
}
};
return hack::get(a);
}
当我从得知这个答案 , .*&
实际上是两个运营商,在指针从产生&hack::c
(其类型ADAPTER::container_type ADAPTER::*
)为对象或.*
操作来获取基础容器本身。 hack
能够访问受保护的成员,但得到的指针后,保护丢失。 所以a.*(&hack::c)
是允许的。
Answer 4:
不,没有这样做的标准方式。 至于访问的标准,它是不可用ONN网站,你必须购买一份! 不过,也有草案的各个副本可在这里 。
Answer 5:
这SGI页面是最“官方”的在线文档,我相信。
你不能让底层容器直接访问的原因是,该适配器改变使用模式,并具有可用的基础容器的方法将违反新的使用模式。 例如:
2此限制队列在所有存在的唯一理由。 任何容器,既前插入序列和后插入序列可以用作一个队列; 双端队列,例如,有成员函数前,后,push_front,的push_back,pop_front和pop_back使用容器适配器队列而不是容器双端队列的唯一原因是为了说清楚,你仅执行队列操作,并没有其他的操作。 http://www.sgi.com/tech/stl/queue.html
如果你想解决这个问题的设计功能,你可以这样做:
template <typename T>
class clearable_queue : public std::queue<T>
{
public:
void clear() { c.clear(); }
};
Answer 6:
作为一般规则,以下划线开头的标识符是供应商特定的分机或实现细节。 所以_Get_container()
仅仅是由微软,因为它简化了其实施的补充。 它不打算使用。
至于在哪里可以找到的文件,它分成几个部分。
该权威人士透露,当然,语言标准。 正如尼尔·巴特沃思说,有网上免费提供副本草案(这还是非常有用的。那些到最终版本的差异真的很小)。 或者,你可以买一个副本。 它应该可以从任何一个组织代表ISO在您的国家(可能从bajillion其他的来源)。 你要找的文件是ISO/IEC 14882:2003 Programming Language C++
。 (14882是标准的数字,2003年是最后一次修订的年份。如果你遇到了1998年的版本,你可以使用了。差异是真的两者之间可笑的小,基本上只相当于一些澄清。这是可能是最好的留在草稿的C ++ 0x远,因为变化有更为广泛)
除此之外,标准库中的每一个执行需要记录大量的细节(实现定义的行为,未在标准中规定的事情,但留给库的实现)。 而除此之外,他们大多也提出了整个库的详细文档,以及。
微软有详细的文档可用MSDN 。 文档尊重的标准,所以你知道哪个是哪个,清楚标出所有非标准扩展。
SGI也有在线文档(虽然它是老年人和在某些情况下,并不完全准确)。
IBM已经在其网站上类似的文件,我相信GCC也会做。
Answer 7:
我当然希望没有访问优先级队列的基本容器的方式。 如果你那么你能可能会搞糟优先级队列的内部堆结构。 在任何情况下,这些适配器的一点是,他们只与堆栈或队列,并抽象出所有其他的事情的最小接口为您呈现。 所以,如果你需要使用其他的功能,你应该直接使用原来的容器。
至于STL的文档,你可以看看SGI的STL的文档在这里 。 有SGI的STL和一个在C ++标准之间有一些差别,但他们在该网站上大多注明。 此外, cppreference.com是日趋完善的C ++库的wiki文档。
Answer 8:
你可以写一个子类来检索成员变量c。 看到的libstdc ++此评论。
protected:
/**
* 'c' is the underlying container. Maintainers wondering why
* this isn't uglified as per style guidelines should note that
* this name is specified in the standard, [23.2.3.1]. (Why?
* Presumably for the same reason that it's protected instead
* of private: to allow derivation. But none of the other
* containers allow for derivation. Odd.)
*/
_Sequence c;
Answer 9:
我在哪里可以找到标准库的官方文件?
C ++标准是精装可用,标准书号0470846747.草稿以PDF形式广泛使用,但你必须要小心与官方版本(C ++ 98,03,11或14)匹配。 当前草案超过C ++ 14标准。
文章来源: Is there a way to access the underlying container of STL container adaptors?