Существует ли способ получить доступ к базовому контейнеру адаптеров контейнера STL?

менеджеры по Контексту и" with" Оператор

, Представленный в PEP 343, , менеджер по контексту является объектом, который действует как контекст во время выполнения для комплекта операторов.

, Так как функция использует новые ключевые слова, она постепенно представляется: это доступно в Python 2.5 через __future__ директива. Python 2.6 и выше (включая Python 3) имеет его в наличии по умолчанию.

я использовал "с" оператором много, потому что я думаю, что это - очень полезная конструкция, вот быстрая демонстрация:

from __future__ import with_statement

with open('foo.txt', 'w') as f:
    f.write('hello!')

то, Что происходит здесь негласно, то, что "с" оператором называет специальное предложение __enter__ и __exit__ методы на объекте файла. Детали исключения также передаются __exit__, если какое-либо исключение было повышено от с телом оператора, позволив, чтобы обработка исключений произошла там.

то, Что это делает для Вас в данном случае, - то, что это гарантирует, что файл закрывается, когда выполнение падает из объема with комплект, независимо если это обычно происходит или было ли исключение выдано. Это - в основном способ абстрагировать далеко общий код обработки исключений.

Другие случаи общего использования для этого включают блокировку с потоками и транзакции базы данных.

24
задан AraK 27 July 2009 в 09:16
поделиться

7 ответов

Я нашел следующее решение где-то в Интернете и использую его в своих проектах:

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;
}

Удачи :).

20
ответ дан 28 November 2019 в 23:23
поделиться

Я упомянул об этом в комментарии, но после некоторых размышлений кажется, что это нормальное решение. очередь / стек / priority_queue (то есть все классы адаптеров) все имеют защищенный член c ], который является базовым контейнером (см. ISO / IEC 14882: 2003, раздел 23.2.2.4), поэтому, если вы унаследовали от любого из них, вы можете получить к нему доступ напрямую.

Я знаю, что типичный разум - не наследовать от контейнеров 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 * к адаптеру > * без перенаправления типов. Технически это, скорее всего, сработает ... но я не рекомендую:

    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        

Поэтому я бы рекомендовал использовать typedefs, чтобы упростить переключение между ними. (Также обратите внимание на мой пример, что вам нужно изменить только 1 строку, чтобы изменить ее из очереди на стек из-за широкого использования typedef s).

9
ответ дан 28 November 2019 в 23:23
поделиться

Нет, стандартного способа сделать это не существует. Что касается доступа к стандарту, он недоступен в сети, вам нужно купить копию! Однако есть разные копии черновиков. доступно здесь .

3
ответ дан 28 November 2019 в 23:23
поделиться

Эта страница SGI , я полагаю, является наиболее "официальной" документацией, доступной в Интернете.

Причина, по которой вы не можете получить прямой доступ к базовому контейнеру, заключается в том, что адаптер изменяет шаблон использования, и наличие доступных методов базового контейнера нарушит этот новый шаблон использования. Например:

2 Это ограничение - единственная причина, по которой очередь вообще существует. Любой контейнер, который является как последовательностью передней вставки, так и последовательностью обратной вставки, может использоваться в качестве очереди; deque, например, имеет функции-члены front, back, push_front, push_back, pop_front и pop_back.Единственная причина использовать очередь адаптера контейнера вместо deque контейнера - дать понять, что вы выполняете только операции с очередью и никакие другие операции. http://www.sgi.com/tech/stl/queue.html

If you want to get around this design feature, you can do something like:

template <typename T>
class clearable_queue : public std::queue<T>
{
public:
    void clear() { c.clear(); }
};
3
ответ дан 28 November 2019 в 23:23
поделиться

Как правило, любой идентификатор, начинающийся с подчеркивания, является расширением, зависящим от производителя, или деталью реализации. Итак, _Get_container () - это просто дополнение, сделанное Microsoft, потому что оно упростило их реализацию. Он не предназначен для использования.

Что касается того, где найти документацию, она разделена на несколько частей.

Авторитетный источник, конечно же, является языковым стандартом. Как сказал Нил Баттерворт, есть черновики, доступные бесплатно в Интернете (которые по-прежнему очень полезны. Отличия от окончательной версии действительно минимальны). Как вариант, вы можете купить копию. Он должен быть доступен в любой организации, представляющей ISO в вашей стране (и, вероятно, из миллиарда других источников). Вам нужен документ ISO / IEC 14882: 2003 Язык программирования C ++ . (14882 - стандартное число. 2003 - год последней ревизии. Если вы встретите версию 1998 года, вы тоже можете использовать ее. Различия между ними смехотворно малы и в основном сводятся к некоторым уточнениям. вероятно, лучше всего держаться подальше от черновиков для C ++ 0x, поскольку там изменения намного более обширны)

Кроме того, каждая реализация стандартной библиотеки требует документирования большого количества деталей (поведение, определяемое реализацией , вещи, которые не указаны в стандарте, но оставлены на усмотрение разработчика библиотеки). Кроме того, большинство из них также размещают подробную документацию по всей библиотеке.

Microsoft имеет подробную документацию, доступную на MSDN . Документация соответствует стандарту,

2
ответ дан 28 November 2019 в 23:23
поделиться

I certainly hope there isn't a way to access the underlying container of a priority queue. If you could then you could mess up the internal heap structure of the priority queue. In any case the point of those adaptors is that they only present you with the minimal interface of the stack or queue, and abstract out all the other things. So if you needed to use any other features, you should have used the original container directly.

As for documentation of the STL, you can look at the documentation of SGI's STL here. There are a few differences between SGI's STL and the one in the C++ standard, but they are mostly noted on that site. Also, cppreference.com is a wiki documentation of the C++ library that is becoming more complete.

1
ответ дан 28 November 2019 в 23:23
поделиться

Где я могу найти официальную документацию по стандартной библиотеке?

Стандарт C ++ доступен в твердом переплете, ISBN 0470846747. Черновики стандарта широко доступны в формате PDF, но вам нужно быть осторожным, чтобы сопоставить их с официальными версиями (C ++ 98,03,11 или 14). Текущие проекты превышают стандарт C ++ 14.

-2
ответ дан 28 November 2019 в 23:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: