C++ 有没有办法访问STL容器适配器的底层容器?

C++ 有没有办法访问STL容器适配器的底层容器?,c++,data-structures,stl,standards,C++,Data Structures,Stl,Standards,是否有一种标准的方法来访问堆栈,队列,优先级队列的底层容器 我在VS2008堆栈和队列的实现中找到了一个名为:\u Get\u container()的方法,但没有一个方法用于优先级队列!我认为它无论如何都不是标准的 而且,我知道这是一个愚蠢的问题!在哪里可以找到标准库的官方文档 只是为了澄清一下,我并没有试图搞乱底层容器。我想做的就是: template <class Container> std::ostream& printOneValueContainer(std:

是否有一种标准的方法来访问
堆栈
队列
优先级队列
的底层容器

我在
VS2008
堆栈
队列
的实现中找到了一个名为:
\u Get\u container()
的方法,但没有一个方法用于
优先级队列
!我认为它无论如何都不是标准的

而且,我知道这是一个愚蠢的问题!在哪里可以找到标准库的官方文档


只是为了澄清一下,我并没有试图搞乱底层容器。我想做的就是:

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;
模板
std::ostream和printOneValueContainer(std::ostream和outputstream,Container和Container)
{
Container::const_iterator beg=Container.begin();

outputstream不,没有标准的方法。至于访问标准,它在网上是不可用的,你必须购买一份!但是,有各种各样的草稿副本
.

我当然希望没有办法访问优先级队列的底层容器。如果可以的话,可能会弄乱优先级队列的内部堆结构。在任何情况下,这些适配器的要点是,它们只提供堆栈或队列的最小接口,并抽象出所有其他内容。因此,我如果需要使用任何其他功能,则应直接使用原始容器

STL文档,可以查看SGI的STL文档。SGI的STL和C++标准中的一些差异,但它们在该站点上大多是被注意的。此外,C++的Wiki文档也变得更加完整。

是最“官方”的。我相信可以在网上找到文件

无法直接访问基础容器的原因是适配器更改了使用模式,而使基础容器的方法可用将违反新的使用模式。例如:

此限制是队列存在的唯一原因。任何既是前插入序列又是后插入序列的容器都可以用作队列;例如,deque的成员函数front、back、push_front、push_back、pop_front和pop_back是使用容器适配器队列而不是contain的唯一原因er deque是为了明确您只执行队列操作,而不执行其他操作。

如果您想绕过此设计功能,可以执行以下操作:

template <typename T>
class clearable_queue : public std::queue<T>
{
public:
    void clear() { c.clear(); }
};
模板
类可清除队列:public std::queue
{
公众:
void clear(){c.clear();}
};

一般来说,任何以下划线开头的标识符都是特定于供应商的扩展或实现细节。因此,
\u Get\u container()
只是Microsoft添加的,因为它简化了它们的实现。不打算使用它

至于在哪里找到文档,它分为几个部分

当然,权威来源是语言标准。正如尼尔·巴特沃斯所说,在线上有免费的草稿(这些草稿仍然非常有用。与最终版本的差异非常小)。或者,您也可以购买一份。它应该可以从您所在国家代表ISO的任何组织获得(可能也可以从其他来源获得)。您要查找的文档是
ISO/IEC 14882:2003编程语言C++
。(14882是标准数字。2003年是最后一次修订的年份。如果你遇到1998年的版本,你也可以使用它。两者之间的差异非常小,基本上只是一些澄清。可能最好远离C++0x的草案,因为那里的更改要广泛得多)

除此之外,标准库的每个实现都需要记录大量的细节(实现定义的行为,标准中没有规定,但留给库实现者的事情)。此外,大多数实现还需要记录整个库的详细文档

Microsoft在上提供了详细的文档。该文档尊重标准,并清楚地标记了所有非标准扩展,以便您知道哪个是哪个

也有在线文档(尽管它比较旧,在某些情况下并不完全准确)

IBM在其网站上有类似的文档,我相信GCC也有。

在哪里可以找到标准库的官方文档

C++标准可在精装本,ISBN 0470846747中使用。


标准草案以PDF格式广泛提供,但您必须小心将其与官方版本(C++98、03、11或14)相匹配。当前的草案超过了C++14标准。

我在评论中提到了这一点,但经过一些思考,这似乎是一个不错的解决方案。
队列
/
堆栈
/
优先级队列
(也就是说,所有适配器类)都有一个
受保护的
成员
c
,该成员是底层容器(请参见ISO/IEC 14882:2003第23.2.2.4节),因此如果您从其中任何一个继承,您可以直接访问它

我知道典型的智慧是由于非虚拟DTR而不从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;
    }
}
#包括
#包括
模板
类适配器:公共容器{
公众:
typedef typename Container::Container\u type Container\u type;
容器类型&获取容器(){返回此->c;}
};
int main(){
typedef std::队列C;
typedef适配器容器;
骗局
    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        
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;
}
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);
}
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;