C ++ 11: количество параметров функции шаблона с переменным размером?


87

Как я могу подсчитать количество аргументов функции вариативного шаблона?

то есть:

template<typename... T>
void f(const T&... t)
{
    int n = number_of_args(t);

    ...
}

Как лучше всего реализовать number_of_argsвышеперечисленное?


28
sizeof...(T).
R. Martinho Fernandes

21
@ R.MartinhoFernandes форма «Отправьте свой ответ» находится на несколько дюймов ниже нижней части страницы. ;)
kay

@ kay-SEisevil Я не понимаю, почему у вашего комментария меньше голосов, чем у него.
Sapphire_Brick

Ответы:


103

Просто напишите это:

const std::size_t n = sizeof...(T); //you may use `constexpr` instead of `const`

Обратите внимание, что nэто постоянное выражение (то есть известное во время компиляции), что означает, что вы можете использовать его там, где требуется постоянное выражение, например:

std::array<int,   n>  a; //array of  n elements
std::array<int, 2*n>  b; //array of (2*n) elements

auto middle = std::get<n/2>(tupleInstance);

Обратите внимание, что если вы хотите вычислить агрегированный размер упакованных типов (в отличие от количества типов в пакете), вам нужно сделать что-то вроде этого:

template<std::size_t ...>
struct add_all : std::integral_constant< std::size_t,0 > {};

template<std::size_t X, std::size_t ... Xs>
struct add_all<X,Xs...> : 
  std::integral_constant< std::size_t, X + add_all<Xs...>::value > {};

затем сделайте это:

constexpr auto size = add_all< sizeof(T)... >::value;

В C ++ 17 (и более поздних версиях) вычисление суммы размеров типов намного проще с использованием выражения свертки :

constexpr auto size = (sizeof(T) + ...);

Надеюсь, это поможет.


9
+1 Узнал две вещи; sizeof...и constexpr. :)
Qix - МОНИКА БЫЛА ОФИЦИАЛЬНО

1
Значит, это sizeof...фактически возвращает количество аргументов, а не общий размер хранилища всех аргументов (как sizeofв массиве)?
panzi

@panzi: Да. sizeof ...(T)возвращает количество упакованных типов T. Если вы хотите вычислить агрегированный размер упакованных типов, вам нужно сделать что-то вроде этого: ideone.com/udggBk Я также добавил это в свой ответ.
Nawaz

@panzi: вычисления в моем ответе теперь немного улучшены.
Nawaz

2
В C ++ 17 для вычисления размера отдельных типов аргументов теперь мы можем использовать выражения return (0 + ... + sizeof(t));
свертки
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.