Если у меня есть массив constexpr
из N
целых чисел, как его преобразовать в соответствующий constexpr std::tuple<...>
?Как создать кортеж N T из массива T?
ответ
Вот возможная реализация для сырьевых массивов:
#include<functional>
template<std::size_t... I, std::size_t N>
constexpr auto f(const int (&arr)[N], std::index_sequence<I...>) {
return std::make_tuple(arr[I]...);
}
template<std::size_t N>
constexpr auto f(const int (&arr)[N]) {
return f(arr, std::make_index_sequence<N>{});
}
int main() {
constexpr int arr[] = { 0, 1, 2 };
constexpr auto tup = f(arr);
static_assert(std::get<0>(tup) == 0, "!");
static_assert(std::get<1>(tup) == 1, "!");
static_assert(std::get<2>(tup) == 2, "!");
}
Размер constexpr
массива может быть выведен на compile- время, так что вам не нужно явно указывать.
Этот размер может быть использован внутри для создания набора индексов, чтобы получить элементы из массива и создать кортеж на лету.
Как упоминалось в комментариях, если вы хотите, чтобы обобщить немного больше и принимать как сырые массивы и std::array
с, вы можете сделать это:
#include<functional>
#include<array>
template<std::size_t... I, typename U>
constexpr auto f(const U &arr, std::index_sequence<I...>) {
return std::make_tuple(arr[I]...);
}
template<typename T, std::size_t N>
constexpr auto f(const T (&arr)[N]) {
return f(arr, std::make_index_sequence<N>{});
}
template<typename T, std::size_t N>
constexpr auto f(const std::array<T, N> &arr) {
return f(arr, std::make_index_sequence<N>{});
}
int main() {
constexpr int arr1[] = { 0, 1, 2 };
constexpr auto tup1 = f(arr1);
static_assert(std::get<0>(tup1) == 0, "!");
static_assert(std::get<1>(tup1) == 1, "!");
static_assert(std::get<2>(tup1) == 2, "!");
constexpr std::array<int, 3> arr2 = { 0, 1, 2 };
constexpr auto tup2 = f(arr2);
static_assert(std::get<0>(tup2) == 0, "!");
static_assert(std::get<1>(tup2) == 1, "!");
static_assert(std::get<2>(tup2) == 2, "!");
}
Мне нравится этот ответ, у этого есть более чистый/более тонкий интерфейс. Благодаря! – Short
Я объединил свой ответ с моим, чтобы покрыть как базовый массив, так и std :: array
@Short Я бы не сделал так, как вы это делали для 'std :: array'. Если вы хотите, я могу обновить свой ответ, чтобы покрыть их. – skypjack
Преобразование массива в кортеж использует std::integer sequence, создавая индексы массивов во время компиляции, когда компилятор вызывает вспомогательную функцию для 0..N.
Вот код, который демонстрирует это. http://coliru.stacked-crooked.com/a/b2d6c6ca1f5dc635
////////////////////////////////////////////////////////////////////////////////////////////////////
// tuple_from_array
namespace detail {
template<typename T, std::size_t... Is>
auto constexpr tuple_from_array(T const& arr, std::index_sequence<Is...>)
{
return std::make_tuple(arr[Is]...);
}
template<std::size_t N, typename V, typename T, std::size_t ...Is>
auto constexpr array_from_container(T const& c, std::index_sequence<Is...>)
{
return std::array<V, N>{c[Is]...};
}
} // ns detail
template<typename T>
auto constexpr tuple_from_array(T const& arr)
{
auto constexpr tup_size = std::tuple_size<std::decay_t<T>>::value;
return detail::tuple_from_array(arr, std::make_index_sequence<tup_size>{});
}
template<typename T, std::size_t N>
auto constexpr tuple_from_array(T const (&arr)[N])
{
return detail::tuple_from_array(arr, std::make_index_sequence<N>{});
}
// not safe
template<std::size_t N, typename T>
auto constexpr tuple_from_container(T const& c)
{
using V = typename T::value_type;
return tuple_from_array(detail::array_from_container<N, V>(c, std::make_index_sequence<N>{}));
}
редактировать: Я объединил skypjack @ 's ответ с моей собственной, чтобы покрыть основные массивы запрашиваются в комментариях. Я не могу повторно поставить это как мой собственный ответ в течение двух дней, хотя :(
Публикация полезных вопросов и ответов всегда поощряется. Но ответ «код-дамп» не является воплощением качества. Я предлагаю вам отредактировать его с объяснением. – StoryTeller
Как у этого есть «нулевые накладные расходы во время выполнения»? –
Функции constexpr преобразуют массив в кортеж во время компиляции. Извините, я обновил пример и ссылку на код, чтобы создать экземпляр кортежа как значение constexpr. – Short
- 1. Как удалить \ n, \ t из слова, например "\ n \ t \ t \ t \ tDay недели \ n \ t \ t \ t"?
- 2. Как я могу создать кортеж N типа T?
- 3. Как читать из xml-файла без/n/t/t myValue \ n \ t \ t
- 4. Анализ алгоритма с повторением T (n) = T (n - 1) + T (n - 2) + T (n -3)?
- 5. Как решить T (n) = T (n-1) + n^2?
- 6. Алгоритмическое T (n) = T (n-1) +2
- 7. Как решить уравнение рекурсии T (n) = T (n/2) + T (n/4) + \ Theta (n)?
- 8. Как решить рекурсию T (n) = T (n/2) + T (n/4), T (1) = 0, T (2) = 1 есть T (n) = Θ (n lg φ) , где φ - золотой коэффициент?
- 9. Какова временная сложность T (n) = (T (n-1) + n!)?
- 10. не удается преобразовать из 'T [N] [2]' на 'T [] [2]
- 11. Решение рекуррентного отношения T (n) = T (n-1) * T (n-2) + c, где T (0) = 1 и T (1) = 2
- 12. сложность функции T (N) = T (n/2) + 2^n
- 13. Рекуррентное соотношение: T (n) = T (n - 1) + n - 1
- 14. Как решить это уравнение сложности, T (n) = T (n-3) + T (n-5)
- 15. Как решить T (n) = T (0,2 * n^0,5) + 1?
- 16. Решите T (n) = T (n-1) + n^4 методом замещения
- 17. Python: скрипт извлекает ошибки: u '\ n \ t \ t \ t \ t \ t \ t'
- 18. Ищите строки, содержащие «\ N \t \t абвг»
- 19. Рекуррентное соотношение T (n) = T (n^(1/2)) + T (nn^(1/2)) + n
- 20. Решение рекуррентности T (n) = T (n/3) + T (2n/3) + n^2?
- 21. Сложность повторения T (n) = T (n-2) + 1/lgn?
- 22. Сложность рекурсии: T (n) = T (n-1) + T (n-2) + C
- 23. Как получить T-часть массива T []?
- 24. Решая рекуррентность T (n) = T (n/5) + T (7n/10) + Θ (n)
- 25. временная сложность этого уравнения t (n) = t (n-1) * t (n-1)
- 26. Значение string.split(), переданное модулю python3, интерпретирует '|' как \ n \ t \ t \ t \ t. Зачем?
- 27. T (n) = T (n-1) + O (log n) $ является T (n) = O (n^2) или T (n) = O (n log n)
- 28. Действительно ли T (n)> = T (n-1) истинно?
- 29. Binding const T (& ref) [N] к объекту типа T [N]
- 30. Как решить рекурсивную сложность T (n) = T (n/3) + T (2n/3) + cn
Является ли ваш массив сырой массив или 'станд :: array' или что? –
Зачем вам нужно «кортеж», когда у вас уже есть массив? – Barry