Как найти длину пакета параметров?

Предположим, у меня есть функция шаблона с переменным числом аргументов, например

template<typename... Args>
unsigned length(Args... args);

Как найти длину списка параметров с помощью функции длины?


person Eternal Learner    schedule 05.05.2010    source источник


Ответы (1)


Используйте 1_:

template<typename... Args>
constexpr std::size_t length(Args...)
{
    return sizeof...(Args);
}

Обратите внимание, что вы должны использовать не unsigned, а std::size_t (определено в <cstddef>). Кроме того, функция должна быть константным выражением.


Без использования sizeof...:

namespace detail
{
    template<typename T>
    constexpr std::size_t length(void)
    {
        return 1; // length of 1 element
    }

    template<typename T, typename... Args>
    constexpr std::size_t length(void)
    {
        return 1 + length<Args...>(); // length of one element + rest
    }
}

template<typename... Args>
constexpr std::size_t length(Args...)
{
    return detail::length<Args...>(); // length of all elements
}

Обратите внимание, все полностью не проверено.

person GManNickG    schedule 05.05.2010
comment
Мне было интересно, можем ли мы повторно использовать функцию длины, уменьшая размер аргументов шаблона на каждой итерации и определяя базовый случай, когда количество аргументов становится равным 1. Мы продолжаем увеличивать счетчик на каждой итерации. Я просто не могу поместить свои мысли в код.. - person Eternal Learner; 05.05.2010
comment
@Eternal: да, вы могли бы, но не было бы интереснее решить проблему, чем переопределить оператор? - person Potatoswatter; 05.05.2010
comment
Шаблоны Variadic не действуют как LISP… базовым случаем должен быть пустой список. - person Potatoswatter; 05.05.2010
comment
связанные stackoverflow.com /вопросы/2771016/ - person Motti; 05.05.2010
comment
@Картошка: Что ты имеешь в виду? Как может быть пустой список шаблонов? - person GManNickG; 05.05.2010
comment
Пакет параметров может соответствовать пустому списку. sizeof ... может возвращать 0. 14.3/1: Когда параметр, объявленный шаблоном, представляет собой пакет параметров шаблона (14.5.3), он будет соответствовать нулю или более аргументам шаблона. - person Potatoswatter; 05.05.2010
comment
Что касается сложности построения шаблона функции, соответствующего имени length<>, ответить не могу. Может быть, избежать перегрузок здесь. - person Potatoswatter; 05.05.2010
comment
Я предполагаю, что вы могли бы сделать template<typename ... T> constexpr typename enable_if<sizeof...(T)==0, std::size_t>::type length(void) { return 0; }, но я согласен - лучше использовать для этого шаблон класса. - person Johannes Schaub - litb; 06.05.2010