Возможный дубликат:
В чем разница между использованием структуры с двумя полями и парой?Уважаемые все,
У меня есть небольшой вопрос о парах и структурах. Есть ли преимущества в использовании std :: Некоторое время я использовал пары, но главная проблема - читаемость: Если вы хотите представить, например, дуплекс (int «label», double «value»), вы можете использовать либо a:
typedef std::pair
myElem; , либо
typedef struct { int label; double value; } myElem;
. Код станет более читабельным, если ваши утверждения имеют «семантический» смысл (вы всегда будет знать, что такое x.label. Это не относится к x.first).
Тем не менее, я предполагаю, что использование пары дает преимущество. Он более производительный или что-то еще?
пара
реализована как шаблонная структура
.Он предоставляет вам сокращенную запись для создания (обычно разнородной) пары. Кроме того, существуют некоторые ограничения на типы, которые можно использовать с парой
:
Требования к типу
T1 и T2 должны быть оба быть моделями Assignable. Дополнительный операции имеют дополнительные требования. Пара по умолчанию конструктор может использоваться только в том случае, если оба T1 и T2 являются DefaultConstructible, operator== может использоваться только в том случае, если оба T1 и T2 являются EqualityComparable, и operator< может использоваться только в том случае, если оба T1 и T2 меньше сопоставимых.
(из документации SGI STL std::pair
)
Определение собственного POD может иметь смысл, если типы не следуют ни одному из этих ограничений или если вы не заботитесь о них.
Наконец, я думаю, это вопрос личного выбора/стиля кодирования.
С точки зрения производительности: маловероятно чтобы что-то изменить, вы просто приукрашиваете это.
С точки зрения удобства использования я бы предпочел использовать пользовательскую структуру, которую можно объявить следующим образом (кстати):
struct MyElement
{
int label;
double value;
};
Я ярый сторонник строгой типизации и предпочитаю «настоящую» структуру ( и еще лучше, класс), чем специальный кортеж, когда это больше, чем мимолетная вещь.
Главным образом потому, что:
first
и second
не несут большого значения std: :pair
std::pair нельзя добавлять инварианты класса
. .
Его основное преимущество в том, что он универсальный. Например, когда вы извлекаете что-то из std::map
, вы получаете ключ и связанное с ним значение в качестве первого и второго элементов в std::pair
.
Аналогичным образом, когда вы используете std::equal_range
для поиска набора одинаковых значений в коллекции, вы получаете итераторы к началу и концу диапазона в качестве первого и второго элементов в std::pair
.
Трудно представить себе осмысленные ярлыки, применимые к обоим из них, поэтому они остановились на паре, которая не имеет особого значения, но, по крайней мере, не вводит в заблуждение. Использование 'key' и 'data' будет работать для std::map
, но будет вводить в заблуждение для std::equal_range
(и если вы переключитесь на что-то вроде lower_bound
и upper_bound
, чтобы сделать их более значимыми для std::equal_range
, это было бы одинаково неправильно для элементов в std::map
).
С std::pair вы можете свободно использовать функторы из STL, такие как select1st или select2nd. Точно так же он позволяет вам использовать другие общие функции с вашей парой, такие как operator< и другие. По общему признанию, с появлением boost/tr1 вы могли бы добиться почти такого же эффекта, используя bind.
Тем не менее, ваша точка зрения о читабельности очень верна.