是否有访问STL容器适配器的基础容器的方法吗?(Is there a way to access t

2019-06-17 15:59发布

是否有访问的基础容器的标准方式stackqueuepriority_queue

我发现了一个叫方法: _Get_container()VS2008实现stackqueue ,但没有一个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_queueVS2008的实现。

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号线将其从一个更改queuestack ,因为自由使用的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?