Вопрос

Что std::pair зачем мне это использовать и какие преимущества это дает boost::compressed_pair приносить?

Это было полезно?

Решение

std::pair — это тип данных для группировки двух значений в один объект. std::map использует его для пар ключ-значение.

Пока ты учишься pair, ты можешь проверить tuple.Это как pair но для группировки произвольного количества значений. tuple является частью TR1, и многие компиляторы уже включают его в свои реализации Стандартной библиотеки.

Также ознакомьтесь с главой 1 «Кортежи» книги. Расширения стандартной библиотеки C++:Учебное пособие и справочник Пит Беккер, ISBN-13:9780321412997, для подробного объяснения.

alt text

Другие советы

compressed_pair использует некоторые хитрости шаблонов для экономии места.В C++ объект (маленький o) не может иметь тот же адрес, что и другой объект.

Так что даже если у вас есть

struct A { };

Aразмер не будет равен 0, потому что тогда:

A a1;
A a2;
&a1 == &a2;

будет удерживаться, что не допускается.

Но многие компиляторы будут выполнять так называемую «оптимизацию пустого базового класса»:

struct A { };
struct B { int x; };
struct C : public A { int x; };

Вот это нормально для B и C иметь одинаковый размер, даже если sizeof(A) не может быть нулевым.

Так boost::compressed_pair использует преимущества этой оптимизации и, где это возможно, наследует от одного или другого типа в паре, если она пуста.

Итак, std::pair может выглядеть так (я многое упустил, актеры и т. д.):

template<typename FirstType, typename SecondType>
struct pair {
   FirstType first;
   SecondType second;
};

Это означает, что если либо FirstType или SecondType является A, твой pair<A, int> должно быть больше, чем sizeof(int).

Но если вы используете compressed_pair, его сгенерированный код будет выглядеть примерно так:

 struct compressed_pair<A,int> : private A {
    int second_;
    A first() { return *this; }
    int second() { return second_; }
 };

И compressed_pair<A,int> будет иметь размер sizeof(int).

Иногда вам нужно вернуть два значения из функции, и часто бывает излишне создавать класс только для этого.

std:pair пригодится в таких случаях.

Я думаю, что boost:compressed_pair способен оптимизировать элементы размера 0.Это особенно полезно для тяжелого шаблонного оборудования в библиотеках.

Если вы управляете типами напрямую, это не имеет значения.

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

boost::function<void(int)> f(boost::bind(&f, _1));

Внезапно использование compressed_pair в подобных случаях может иметь большое значение.Что может произойти, если boost::bind сохранит указатель функции и заполнитель _1 как члены сами по себе или в std::pair в себе?Ну, это может раздуться до sizeof(&f) + sizeof(_1).Если предположить, что указатель функции имеет 8 байтов (нередко, особенно для функций-членов), а заполнитель имеет один байт (почему, см. ответ Логана), тогда нам могло бы понадобиться 9 байтов для объекта привязки.Из-за выравнивания это может привести к увеличению размера до 12 байт в обычной 32-битной системе.

boost::function поощряет свои реализации применять оптимизацию небольших объектов.Это означает, что для маленький функторы, небольшой буфер, непосредственно встроенный в boost::function объект используется для хранения функтора.Для более крупных функторов для получения памяти придется использовать кучу с помощью оператора new.Вокруг повышения версия 1.34, было решено принять эта оптимизация, потому что предполагалось, что можно получить очень большой выигрыш в производительности.

Теперь разумный (хотя, возможно, все еще довольно небольшой) предел для такого маленького буфера будет составлять 8 байт.То есть наш довольно простой объект привязки будет нет помещается в небольшой буфер и требует сохранения оператора new.Если объект привязки выше будет использовать compressed_pair, он фактически может уменьшить свой размер до 8 байт (или 4 байтов для указателя функции, не являющейся членом), поскольку заполнитель — это не что иное, как пустой объект.

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

Это стандартный класс для хранения пары значений.Он возвращается/используется некоторыми стандартными функциями, например std::map::insert.

boost::compressed_pair утверждает, что более эффективен: глянь сюда

std::pair пригодится для пары других классов-контейнеров в STL.

Например:

std::map<>
std::multimap<> 

Оба хранят std::пары ключей и значений.

При использовании карты и мультикарты вы часто получаете доступ к элементам, используя указатель на пару.

Дополнительная информация:boost::compressed_pair полезен, когда один из типов пары является пустой структурой.Это часто используется в метапрограммировании шаблонов, когда типы пары программно выводятся из других типов.В конце у вас обычно возникает некая форма «пустой структуры».

Я бы предпочел std::pair для любого «нормального» использования, если только вы не увлекаетесь тяжелым метапрограммированием шаблонов.

Это не что иное, как структура с двумя переменными под капотом.

Мне вообще не нравится использовать std::pair для возврата функций.Читатель кода должен будет знать, что такое .first и что такое . Second.

Компромисс, который я иногда использую, заключается в немедленном создании постоянных ссылок на .first и . Second, при этом четко называя ссылки.

Для чего нужен std::pair, зачем мне его использовать?

Это такой же простой кортеж из двух элементов.Это было определено в первой версии СТЛ во времена, когда компиляторы не поддерживали широко шаблоны и методы метапрограммирования, которые требовались для реализации более сложных типов кортежей, таких как Boost.Tuple.

Это полезно во многих ситуациях. std::pair используется в стандартных ассоциативных контейнерах.Его можно использовать как простую форму диапазона. std::pair<iterator, iterator> - поэтому можно определить алгоритмы, принимающие один объект, представляющий диапазон, вместо двух итераторов по отдельности.(Это полезная альтернатива во многих ситуациях.)

Иногда есть две части информации, которые вы всегда передаете вместе, будь то параметр, возвращаемое значение или что-то еще.Конечно, вы могли бы написать свой собственный объект, но если это всего лишь два маленьких примитива или что-то подобное, иногда пара кажется вполне подходящей.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top