Различие в расположении памяти вектора пар и вектора структур, содержащих два элемента - C ++ / STL - PullRequest
4 голосов
/ 16 декабря 2011

Является ли расположение в памяти test1 и test2 одинаковым?

std::vector<std::pair<int,int> > test1;
std::vector<mystruct>       test2;

где mystruct определяется как:

struct mystruct{
  int a;
  int b;
 };

Ответы [ 4 ]

3 голосов
/ 16 декабря 2011

Логически, std::pair<int, int> должно быть определено так же.

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

Примечание: Если вы считаете абсурдом быть иначе, я могу привести вам пример того, как это можно определить иначе. Представьте, что в других классах шаблонов stl, использующих std::pair, они чувствуют, что было бы удобно (по любой причине) иметь указатель на узел, содержащий пару, в паре. Таким образом, они могли бы внутренне добавить указатель на класс пары, не нарушая при этом никаких правил. Ваше предположение тогда может привести к хаосу. Я бы сказал, что вряд ли они это сделают, да, но пока они не принуждаются к этому макету, может случиться что угодно.

2 голосов
/ 16 декабря 2011

Если вы увидите на cplusplus.com, вы увидите, что это структура пары:

template <class T1, class T2> struct pair
{
  typedef T1 first_type;
  typedef T2 second_type;

  T1 first;
  T2 second;
  pair() : first(T1()), second(T2()) {}
  pair(const T1& x, const T2& y) : first(x), second(y) {}
  template <class U, class V>
    pair (const pair<U,V> &p) : first(p.first), second(p.second) { }
}

Точно так же, я бы сказал, за исключением некоторых фактов: ну, начиная стот факт, что пары совместимы с контейнерами std и все это, например, карты.Кроме того, пары уже созданы и уже имеют конструкторы для вас.

РЕДАКТИРОВАТЬ: Я также забыл упомянуть, что у вас будет для вас std :: make_pair, который позволит вам пропустить выделение памяти и сделать свой собственныйпары в структуре, и у вас тоже есть определенные операторы сравнения и присваивания.

1 голос
/ 16 декабря 2011

В любой разумной реализации std::pair они будут иметь одинаковое расположение.Но возникает вопрос: почему это важно?Вы не должны делать двоичное присваивание от одного к другому.

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

struct mystruct{
  int a;
  int b;

  mystruct(const std::pair<int,int> &rhs) { a=rhs.first; b=rhs.second; }
  std::pair<int,int> as_pair() { return std::make_pair(a, b); }
 };
1 голос
/ 16 декабря 2011

Да, по крайней мере, в режиме выпуска он будет того же размера.

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

1) Стандарт использует много дополнительных средств отладки. Это делает размеры классов разными в режиме отладки и выпуска. Так что вполне возможно, что std :: pair больше в режиме отладки.

2) Стандарт может измениться внутренне. Нет гарантии, что std :: pair не изменит расположение памяти в другой версии std. Поэтому, если вы полагаетесь на это, вы должны жить со страхом, что однажды это может не сработать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...