Boost C бібліотека Tuple - статичні контейнери
Тип tuple (абоn-tuple) цеколекціяелементів фіксованого розміру (див. інші визначення). Пари (p airs), трійки (triples), четвірки (quadruples) і так далі всі є об'єктами типу tuples. У мові програмування tuple це об'єкт даних, що містить інші об'єкти як елементи. Ці елементи можуть бути різними типами.
Використання типу tuple зручне в різних умовах. Наприклад, тип tuple полегшує створення функції, яка повертає більш ніж одне значення.
Деякі мови програмування , такі як ML, Python і Haskell мають вбудовану підтримку для tuple . На жаль, мова C++ не має такої підтримки. Бібліотека Boost. Tuple містить реалізацію типу tuple у вигляді шаблонів.
Примітка перекладача: при перекладі словаtupleми використовували термінкортежзамість корявої калькитупл.
Вміст
Додаткові деталі
Розширені можливості (описані деякі метафункції та ін.).
Використання бібліотеки
Для використання бібліотеки просто увімкніть рядок:
Оператори порівняння можуть бути підключені так:
Для використання операторів введення/виводу для кортежів,
Хідери tuple_io.hpp і tuple_comparison.hpp обидва включають tuple.hpp.
Типи до ортежів
Кортеж виходить конкретизацією шаблону tuple. Параметри цього шаблону задають типи елементів, що зберігаються. Поточна версія підтримує кортежі, що містять від 0 до 10 елементів. Якщо необхідно, верхня межа може бути збільшена до, скажімо, кількох десятків. Зберігається може мати будь-який тип C++. Зверніть увагу, що void і звичайні функції є коректними типами C++, але ці об'єктитипів що неспроможні існувати. Отже, якщо кортеж містить такі типи елементів, об'єкт типу tuple може існувати , але об'єкти відповідних типів елементів - немає. Є природні обмеження на типи елементів, які не можуть бути скопійовані, або не можуть бути сконструйовані за замовчуванням (див. 'Конструювання tuple').
Конструювання кортежів
Конструктор tuple отримує елементи кортежу як аргументи. Дляn-елементних коотежів можна викликати конструктор з числом аргументівk, де 0
Можна оголосити тип кортежу, для якого не можна побудувати об'єкт. Це трапляється , якщо елемент , який не може бути ініціалізований , має менший індекс , ніж елемент , який вимагає ініціалізації. Наприклад, tuple.
У результаті кортеж - це по суті просто група індивідуальних елементарних конструкцій.
Кортежі можуть бути створені за допомогою допоміжної функції make_tuple (порівняй std::make_pair). Це робить створення кортежів більш зручним, позбавляючи програміста необхідності явно оголошувати типи елементів:
За умовчанням, типи елементів наводяться до простих непосилальних типів. Наприклад:
Виклик make_tuple повертає об'єкт колекції типу tuple.
Аргумент у вигляді масиву функції make_tuple за замовчуванням наводиться до посилання на константний тип , тому масиви не потрібно обгортати за допомогою функції cref . Наприклад:
Цей код створює об'єкт типу tuple (зверніть увагу на те, що тип рядкового літералу це масив константних символів, а не const char* ). Однак, щоб змусити функцію make_tuple створити кортеж з елементом типу неконстантний масив, можна використовувати обгортку ref.
Покажчики на функцію наводяться до простого не-посилального типу, тобто допростий покажчик на функцію. Кортеж може також зберігати посилання на функцію, але такий кортеж не може бути сконструйований за допомогою функції make_tuple (бо в результаті вийде тип константної функції, що неприпустимо):
Доступ до елементів до ортежу
Доступ до елементів кортежу здійснюється за допомогою виразу: або
де t це об'єкт типу tuple і N це цілий константний вираз , що задає індекс елемента в кортежі. Залежно від того, чи кваліфікований об'єкт t як константний чи ні, get повертає N-й елемент як посилання на константний або не-константний тип. Індекс першого елемента 0 тому N повинен бути в діапазоні від 0 до (включно) k-1 , де k це число елементів в кортежі. Порушення цих обмежень виявляються під час компіляції. Приклади:
Зверніть увагу на те, що функція get член класу не підтримується з компілятором MS Visual C++. Більше того, цей компілятор має проблеми з пошуком функції get не члена класу без явної кваліфікації простору імен. Отже, при використанні компілятора MS Visual Studio C++ всі виклики функції l get повинні бути кваліфіковані як tuples:: get (a_tuple).
В обох випадках виконуються такі перетворення: char-> int , B* -> A* (покажчик похідного класу на покажчик базового класу), B -> C (яке задане користувачем перетворення) та D -> C (визначена користувачем перетворення).
Зверніть увагу, що також визначено присвоєння типу std::pair :
Оператори порівняння
Кортежі визначають оператори ==, !=, і >= через відповідні оператори своїх елементів. Це означає, що якщо будь-який з цих операторів визначений для всіх елементів двох кортежів, тоді цей же оператор визначено і длясамих кортежів. Оператори рівності для двох кортежів a та b визначено так:
1. a == b якщо для кожного i справедливо ai == bi
2. a! = b якщо існує такий індекс i, що ai! = bi
Оператори , і реалізують лексикографічне впорядкування.
Зверніть увагу на те, що спроба порівняти два кортежі різної довжини призведе до помилки часу компіляції.
Крім цього, оператори порівняння слідують звичайному для C/C++ принципу: порівняння елементів починається з першого і продовжується лише до першого хибного результату.
Зв'язки (tiers)
Наведена вище функція tie створює кортеж типу tuple. Такий результат може бути досягнутий викликом make_tuple(ref(i), ref(c), ref(a)) .
Кортеж , який містить неконстантні посилання як елементи , може бути використаний для 'розпаковування' іншого кортежу. Наприклад:
Цей код друкує 1-5.5 на стандартну консоль. Операції розпакування кортежів можна знайти, наприклад, в мовах ML та Python. Це дуже зручно при виклику функцій, які повертають об'єкти типу tuple.
Механізм зв'язування також працює із шаблонами типу std::pair :
Об'єкт i gnore
У бібліотеці Boost.Tuple є також об'єкт ignore, який дозволяє ігнорувати елемент, значення якого присвоюється з кортежу. Ідея полягає в тому, що функція може повернути кортеж, тільки частина якого становить інтерес. Наприклад (зверніть увагу, що ignore оголошений у підпросторі імен tuples):
Операції з потоками
Глобальний operator перевантажений для std::ostream так що кортежі виводяться шляхом рекурсивного виклику operator для кожного елемента.
Аналогічно, глобальний оператор operator>> був перевантажений для вилучення кортежів з std::istream шляхомрекурсивного виклику operator>> для кожного елемента.
За замовчуванням роздільником між елементами є пропуск, і весь кортеж полягає в круглі дужки. Наприклад:
на виході дає: (1.0 2 Howdy folks!)
Бібліотека Boost.Tuples визначає триманіпуляторидля зміни поведінки за замовчуванням:
- set_open(char) задає символ, який виводиться перед першим елементом.
- set_close(char) задає символ, який виводиться після останнього елемента.
- set_delimiter(char) визначає символ розділювача між елементами.
Зверніть увагу, що ці маніпулятори визначені у підпросторі імен tuples. Наприклад:
на виході друкує той самий кортеж a у вигляді: [1.0,2, Howdy folks!]
Ті ж маніпулятори так само працюють із operator>> та istream. Припустимо, що потік cin містить такі дані:
прочитає ці дані у кортежі i j .
Зверніть увагу, що вилучення кортежів з елементами типу std::string або C-рядками в загальному випадку не працює, оскільки записаний у потік кортеж не може бути однозначно розібраний назад на елементи.
Ефективність
Всі функції для доступу до елементів кортежів tuple та функції конструювання є невеликими однорядковими inline функціями. Тому сучасні компілятори можуть оптимізувати накладні витрати на операції з кортежами порівняно з написаним вручну кодом із кортежами у вигляді класів. Зокрема, для сучасних компіляторів немає різниці в ефективності виконання для коду:
і для цього коду:
Однак є компілятори, що широко використовуються (наприклад bcc 5.5.1) , які не можуть виконати оптимізацію для такого використання кортежів .
Залежно від оптимізуючихЗдібностей компілятора , механізм зв'язок може мати невелику втрату ефективності в порівнянні з використанням неконстантних посилань як аргументів для передачі безлічі значень з функції. Наприклад, припустимо, що такі функції f1 і f2 мають однакову функціональність:
Тоді виклик #1 може бути трохи швидшим, ніж #2 в наведеному нижче коді:
[1, 2] для більш детального обговорення ефективності.
Ефекти часу компіляції
Компілювання кортежів може бути дуже повільним через велику кількість конкретизацій шаблонів. Залежно від типу компілятора та довжини кортежу, час компіляції може бути до 10 разів більшим, ніж при використанні написаних вручну класів, таких як наведений раніше клас hand_made_tuple. Однак реальні програми зазвичай містять багато коду на додаток до кортежів tuple, тому різниця в часі компіляції виявляється несуттєвою. Для програм, які використовують кортежі дуже часто, було зафіксовано збільшення часу компіляції від 5 до 10 відсотків. Для цих тестових програм потреби в пам'яті для компіляції зростали від 22% до 27%. також [1, 2].
Портабельність
library code is(?) standard C++ and thus the library works with standard conforming compiler. Нижче наведено список компілерів і відомих проблем з одним комп'ютером: