◐ Shell
clean mode source ↗

std::tuple_size — cppreference.com

Материал из cppreference.com

<tbody> </tbody>

Определено в заголовочном файле <tuple>

Определено в заголовочном файле <array>

Определено в заголовочном файле <utility>

Определено в заголовочном файле <ranges>

(начиная с C++20)

template< class T > struct tuple_size; // не определён

(1) (начиная с C++11)

template< class T > struct tuple_size< const T > : std::integral_constant<std::size_t, std::tuple_size<T>::value> { };

(2) (начиная с C++11)

template< class T > struct tuple_size< volatile T > : std::integral_constant<std::size_t, std::tuple_size<T>::value> { };

(3) (начиная с C++11)
(устарело в C++20)

template< class T > struct tuple_size< const volatile T > : std::integral_constant<std::size_t, std::tuple_size<T>::value> { };

(4) (начиная с C++11)
(устарело в C++20)

Предоставляет доступ к количеству элементов в типе tuple-like в виде константного выражения времени компиляции.

1) Основной шаблон не определён. Чтобы сделать тип tuple-подобным, требуется явная (полная) или частичная специализация.

2-4) Специализации для cv-квалифицированных типов повторно используют value из соответствующих cv-неквалифицированных версий по умолчанию.

std::tuple_size взаимодействует с ядром языка: он может обеспечить поддержку структурной привязки в tuple-подобном случае.

(2-4) являются дружественными к SFINAE: если std::tuple_size<T>::value является неправильно сформированым, когда рассматривается как невычисленный операнд, он не предоставляет элемент value. Проверка доступа выполняется как бы в контексте, не связанном с tuple_size и T. Учитывается только действительность непосредственного контекста выражения. Это позволяет

#include <utility>
struct X { int a, b; };
const auto [x, y] = X(); // объявление структурной привязки сначала пытается
                         // использовать tuple_size<const X>, который пытается
                         // использовать tuple_size<X>::value, затем возникает
                         // программная ошибка, привязка к общедоступным элементам данных
(начиная с C++17)

Специализации

Стандартная библиотека предоставляет следующие специализации для стандартных библиотечных типов:

Все специализации std::tuple_size соответствуют UnaryTypeTrait с базовой характеристикой std::integral_constant<std::size_t, N> для некоторого N.

Пользователи могут специализировать std::tuple_size для определяемых программой типов, чтобы сделать их tuple-подобными. Специализации, определяемые программой, должны соответствовать вышеуказанным требованиям.

Обычно для настройки требуется только специализация для cv-неквалифицированных типов.

Шаблон вспомогательной переменной

<tbody> </tbody>

Определено в заголовочном файле <tuple>

template< class T > inline constexpr std::size_t tuple_size_v = tuple_size<T>::value;

(начиная с C++17)

Унаследован от std::integral_constant

Константы элементы

для стандартной специализации количество элементов в tuple-подобном типе T
(public static константа-элемент)

Функции-элементы

преобразует объект в std::size_t, возвращает value
(public функция-элемент)
возвращает value
(public функция-элемент)

Типы элементы

Тип Определение
value_type std::size_t
type std::integral_constant<std::size_t, value>

Пример

#include <array>
#include <cstddef>
#include <ranges>
#include <tuple>
#include <utility>

template <class T, std::size_t Size> struct Arr { T data[Size]; };
// определяемая программой специализация std::tuple_size:
template <class T, std::size_t Size> struct std::tuple_size<Arr<T, Size>>
    : public integral_constant<std::size_t, Size> {};

int main()
{
    using tuple1 = std::tuple<int, char, double>;
    static_assert(3 == std::tuple_size_v<tuple1>); // использует using шаблон (C++17)

    using array3x4 = std::array<std::array<int, 3>, 4>;
    static_assert(4 == std::tuple_size<array3x4>{}); // использует operator std::size_t

    using pair = std::pair<tuple1, array3x4>;
    static_assert(2 == std::tuple_size<pair>()); // использует operator()

    using sub = std::ranges::subrange<char*, char*>;
    static_assert(2 == std::tuple_size<sub>::value);

    using Arr5 = Arr<int, 5>;
    static_assert(5 == std::tuple_size_v<Arr5>);
}

Отчёты о дефектах

Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:

Номер Применён Поведение в стандарте Корректное поведение
LWG 2212 C++11 специализации для cv типов не требовались в некоторых заголовках,
что приводило к двусмысленности
требуются

Смотрите также