Подтвердить что ты не робот

Struct с 2 ячейками против std:: pair?

Возможный дубликат:
В чем разница между использованием структуры с двумя полями и парой?

Дорогой,

У меня есть маленький вопрос о парах и структуре. Есть ли какое-либо преимущество в использовании std:: pair вместо структуры с двумя ячейками? Я использовал пару некоторое время, но главная проблема - читаемость: Если вы хотите представить, например, duple (int "label", double "value" ), вы можете использовать либо:

typedef std::pair<int,double> myElem;

или

typedef struct {
    int label;
    double value;
} myElem;

Код становится более читаемым, если ваши утверждения имеют "смысловой" смысл (вы всегда будете знать, что такое x.label, что не в случае с x.first).

Однако, я думаю, что есть преимущество, использующее пару. Является ли это более совершенным или что-то еще?

4b9b3361

Ответ 1

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

Требования к типу

T1 и T2 должны оба быть моделями Assignable. дополнительный операции имеют дополнительные требования. Пара по умолчанию конструктор может использоваться только в том случае, если оба T1 и T2 являются DefaultConstructible, оператор == может использоваться только в том случае, если оба T1 и T2 являются EqualityComparable, и Оператор < может использоваться только в том случае, если оба T1 и T2 являются LessThanComparable.

(из SGI STL std::pair документация)

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

Наконец, я думаю, что это вопрос стиля личного выбора/кодирования.

Ответ 2

С точки зрения производительности: вряд ли что-то изменит, вы просто сахарируете его.

В терминах удобства использования я предпочел бы использовать настраиваемую структуру, которая может быть объявлена ​​таким образом (кстати):

struct MyElement
{
  int label;
  double value;
};

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

В основном потому, что:

  • Как вы отметили, first и second не имеют большого значения
  • Вы не можете добавлять методы/другие поля в std::pair
  • Вы не можете добавить инварианты класса к std::pair

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

Ответ 3

Однако, я думаю, что есть преимущество, использующее пару. Является ли это более совершенным или что-то еще?

Я сомневаюсь, что экземпляр std::pair - это всего лишь struct. std::pair поставляется с operator<. Но это не должно быть слишком сложно сделать для себя struct только с двумя членами.

Итак, я обычно делаю так, как вы рассуждали: a struct с выделенными именами членов легче читать, чем first и second.

Ответ 4

Его основное преимущество заключается в том, что он общий. Например, когда вы извлекаете что-то из std::map, вы получаете ключ и связанное значение в качестве первого и второго элементов в std::pair.

Аналогично, когда вы используете std::equal_range для поиска набора равных значений в коллекции, вы получаете итераторы в начале и конце диапазона в качестве первого и второго элементов в std::pair.

Трудно представить значащие ярлыки, которые будут применяться к обоим, поэтому они поселились для пары, которая не имеет большого значения, но, по крайней мере, не вводит в заблуждение. Использование "ключа" и "данных" будет работать для std::map, но вводить в заблуждение для std::equal_range (и если вы переключились на что-то вроде lower_bound и upper_bound, чтобы сделать их более значимыми для std::equal_range, это одинаково ошибочно для элементов в std::map).

Ответ 5

С помощью std:: pair вы можете использовать функторы из STL, такие как select1st или select2nd. Аналогично, это позволяет вам использовать другие общие функции с вашей парой, такими как оператор < и другие. По общему признанию, с появлением boost/tr1 вы можете добиться такого же эффекта, используя bind.

Ваша точка зрения на читаемость очень верна.