




Иногда вам нужно вернуть 2 значения из функции, и часто бывает излишним пойти и создать класс только для этого.
std: pair пригодится в таких случаях.
Я думаю, что boost: compressed_pair может оптимизировать элементы размера 0. Что в основном полезно для тяжелой машины шаблонов в библиотеках.
Если вы действительно контролируете типы напрямую, это не имеет значения.
std :: pair пригодится для пары других контейнерных классов в STL.
Например:
std::map<>
std::multimap<>
Оба хранят std :: пары ключей и значений.
При использовании карты и мульти-карты вы часто получаете доступ к элементам, используя указатель на пару.
Это стандартный класс для хранения пары значений. Он возвращается / используется некоторыми стандартными функциями, такими как std::map::insert.
boost::compressed_pair утверждает, что он более эффективен: глянь сюда
Иногда есть две части информации, которые вы просто всегда передаете вместе, будь то в качестве параметра, или возвращаемого значения, или чего-то еще. Конечно, вы можете написать свой собственный объект, но если это всего лишь два небольших примитива или что-то подобное, иногда пара кажется вполне подходящей.
std::pair - это тип данных для группировки двух значений как одного объекта. std::map использует его для пар ключ-значение.
Пока вы изучаете pair, вы можете проверить tuple. Это похоже на pair, но для группировки произвольного количества значений. tuple является частью TR1, и многие компиляторы уже включают его в свои реализации стандартной библиотеки.
Кроме того, см. Главу 1 «Кортежи» книги Расширения стандартной библиотеки C++: Учебное пособие и справочник Пита Беккера, ISBN-13: 9780321412997, для подробного объяснения.

Кроме того, в библиотеках boost есть хорошая реализация кортежей, если ваш компилятор еще не поддерживает TR1.
Дополнительная информация: boost :: compressed_pair полезна, когда один из типов пары является пустой структурой. Это часто используется в метапрограммировании шаблонов, когда типы пары программно выводятся из других типов. В конце у вас обычно есть некоторая форма «пустой структуры».
Я бы предпочел std :: pair для любого «нормального» использования, если только вы не занимаетесь тяжелым метапрограммированием шаблонов.
Это не что иное, как структура с двумя переменными под капотом.
На самом деле мне не нравится использовать std :: pair для возврата функций. Читатель кода должен знать, что такое .first и что .second.
Иногда я использую компромисс: немедленно создаю постоянные ссылки на .first и .second, четко называя ссылки.
Я согласен с вами насчет соглашения об именах. Усложняет обслуживание.
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 может выглядеть так (я многое упустил, ctors и т. д.):
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).
Я просто читал эту мысль, черт возьми, ответ этого парня продуман и полон, а потом понял, кто это был, и даже немного не удивился! Привет, Логан!
я пропустил что-то важное? скажите, пожалуйста, кто этот парень? я тоже хочу его похвалить :)
Если нет двух Логанов Капалдо, я работаю с Логаном.
о, понятно :) спасибо, что дали мне знать. желаю вам, ребята, удачи :)
Насколько я знаю, меня не двое. Привет, Дом! :)
Кроме того, я хотел бы добавить, что compressed_pair совершенно бесполезен, если вы не занимаетесь сложным универсальным программированием, поскольку нет (и я имею в виду) реальных ситуаций, когда вы помещаете класс без данных в пару.
@ViktorSehr Похоже, это может быть полезно для хранения пользовательского средства удаления / клонирования для класса интеллектуального указателя. В общем, у вас не будет никаких данных-членов в классе, но вам все равно потребуется поддержка распределителей / освобождающих память с отслеживанием состояния. Это то, что я ищу здесь. Я не думаю, что это «тяжелое» универсальное программирование.
Может показаться странным слышать, что 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 байтов для указателя на функцию, не являющуюся членом), потому что заполнитель - это не что иное, как пустой объект.
Таким образом, то, что может показаться пустой тратой времени на размышления всего лишь о нескольких байтах, на самом деле может оказать значительное влияние на производительность.
What is std::pair for, why would I use it?
Это такой же простой двухэлементный кортеж. Он был определен в первой версии STL во времена, когда компиляторы не широко поддерживали шаблоны и методы метапрограммирования, которые требовались бы для реализации более сложного типа кортежа, такого как Boost.Tuple.
Это полезно во многих ситуациях. std::pair используется в стандартных ассоциативных контейнерах. Его можно использовать как простую форму диапазона std::pair<iterator, iterator> - поэтому можно определять алгоритмы, принимающие один объект, представляющий диапазон, вместо двух итераторов по отдельности.
(Это полезная альтернатива во многих ситуациях.)
И вы можете использовать boost :: tie для написания кода, который приближается к «a, b = func ();». Вместо явного создания экземпляра пары вы пишете: «boost :: tie (a, b) = func ();».