Элементы хранения C ++ 0x в обратном порядке - PullRequest
6 голосов
/ 06 марта 2011

После небольшого исследования я обнаружил, что C ++ 0x сохраняет элементы в кортеже назад в памяти.

Например, возьмите этот код:

std::tuple<char, char, char> x('\0', 'b 'a');
char* y = (char*)&x;
std::cout << sizeof(x) << std::endl;
std::cout << y << std::endl;

При компиляциис GCC 4.5.2 я получаю следующий вывод:

3
ab

Это изначально озадачило меня.Почему данные хранятся в обратном направлении?После поиска непреднамеренно запутанных заголовков GNU, я заметил, что реализация была похожа на это:

template<typename head, typename... tail> class tuple<head, tail...> : public tuple<tail...>
{
  head value;
  ...
};

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

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

Как насчетчто-то вроде этого?

template<typename... head, typename tail> class tuple<head..., tail> : public tuple<head...>
{
  tail value;
  ...
};

В соответствии с GCC 4.5.2:

error: parameter pack argument ‘head ...’ must be at the end of the template argument list

Если это не станет возможным в будущем, я в значительной степени застрял в поиске другого способареализовать это.Есть ли другой способ?Какой-нибудь способ обмануть GCC, чтобы получить правильно упорядоченный кортеж по памяти?

Ответы [ 2 ]

7 голосов
/ 06 марта 2011

Макет кортежа, который вы исследуете, является неопределенной деталью реализации кортежа. Другие реализации будут иметь другие макеты. Если вы напишите в этот файл, в зависимости от макета gcc, ваш код может быть не переносимым на другие std :: libs.

Реализация кортежа libc ++ (например) имеет противоположный (по порядку) макет.

6 голосов
/ 06 марта 2011

Почему вас волнует, что такое реализация кортежа? Программирование для интерфейса, а не для реализации .

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

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