Как шаблон функции может определить количество вложений в initializer_list? - PullRequest
1 голос
/ 09 марта 2020

У меня есть шаблон функции, который принимает произвольно вложенный список и возвращает массив:

#include <array>
#include <initializer_list>

template<size_t N, typename List>
std::array<size_t,N> some_function (const List& list)
{
    // N is the number of times the list is nested.
    std::array<size_t,N> arr;
    return arr;
}

Когда я использую эту функцию для некоторого вложенного std::initializer_list, например:

int main () {
    using List = std::initializer_list<std::initializer_list<double>>;
    List list = {{1.,2.,3.},{4.,5.,6.}};

    std::array<size_t,2> arr;
    arr = some_function (list);
    return 0;
}

Я получаю сообщение об ошибке, что тип N не может быть выведен

не удалось вывести параметр шаблона 'N'

Вопрос

  • Как я могу улучшить свой шаблон функции для определения количества вложений списка?
  • Есть ли в этом случае альтернативы лучше, чем std::initializer_list?

1 Ответ

4 голосов
/ 09 марта 2020

Вы можете написать два перегруженных constexpr шаблона функций для расчета вложенного времени с помощью std::enable_if и SFINAE .

// types have not member type value_type
template <typename T, typename = void>
struct has_value_type: std::false_type {};
// types have member type value_type
template <typename T>
struct has_value_type<T, std::void_t<typename T::value_type>> : std::true_type {};

// return nested times as 0 for types without member type value_type
template<typename T>
constexpr std::enable_if_t<!has_value_type<T>::value, size_t> get_nested_times() {
    return 0;
}
// return nested times as 1 plus times got on the nested type recursively
template<typename T>
constexpr std::enable_if_t<has_value_type<T>::value, size_t> get_nested_times() {
    return 1 + get_nested_times<typename T::value_type>();
}

тогда вы можете получить вложенные времена во время компиляции как

template<typename List>
auto some_function (const List& list)
{
    // N is the number of times the list is nested.
    constexpr auto N = get_nested_times<List>();
    std::array<size_t, N> arr;
    return arr;
}

LIVE

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