C++
std :: integer_sequence
Suche…
Einführung
std::integer_sequence<Type, Values...>
repräsentiert eine Folge von Werten des Typs Type
wobei Type
einer der integrierten Integer-Typen ist. Diese Sequenzen werden bei der Implementierung von Klassen- oder Funktionsvorlagen verwendet, die vom Positionszugriff profitieren. Die Standardbibliothek enthält auch "Factory" -Typen, die aufsteigende Folgen von ganzzahligen Werten nur aus der Anzahl der Elemente erstellen.
Drehen Sie ein std :: Tupel in Funktionsparameter
Ein std::tuple<T...>
kann verwendet werden, um mehrere Werte zu übergeben. Es könnte beispielsweise verwendet werden, um eine Folge von Parametern in einer Warteschlange zu speichern. Bei der Verarbeitung eines solchen Tupels müssen seine Elemente in Funktionsaufrufargumente umgewandelt werden:
#include <array>
#include <iostream>
#include <string>
#include <tuple>
#include <utility>
// ----------------------------------------------------------------------------
// Example functions to be called:
void f(int i, std::string const& s) {
std::cout << "f(" << i << ", " << s << ")\n";
}
void f(int i, double d, std::string const& s) {
std::cout << "f(" << i << ", " << d << ", " << s << ")\n";
}
void f(char c, int i, double d, std::string const& s) {
std::cout << "f(" << c << ", " << i << ", " << d << ", " << s << ")\n";
}
void f(int i, int j, int k) {
std::cout << "f(" << i << ", " << j << ", " << k << ")\n";
}
// ----------------------------------------------------------------------------
// The actual function expanding the tuple:
template <typename Tuple, std::size_t... I>
void process(Tuple const& tuple, std::index_sequence<I...>) {
f(std::get<I>(tuple)...);
}
// The interface to call. Sadly, it needs to dispatch to another function
// to deduce the sequence of indices created from std::make_index_sequence<N>
template <typename Tuple>
void process(Tuple const& tuple) {
process(tuple, std::make_index_sequence<std::tuple_size<Tuple>::value>());
}
// ----------------------------------------------------------------------------
int main() {
process(std::make_tuple(1, 3.14, std::string("foo")));
process(std::make_tuple('a', 2, 2.71, std::string("bar")));
process(std::make_pair(3, std::string("pair")));
process(std::array<int, 3>{ 1, 2, 3 });
}
Solange eine Klasse std::get<I>(object)
und std::tuple_size<T>::value
, kann sie mit der obigen Funktion process()
werden. Die Funktion selbst ist völlig unabhängig von der Anzahl der Argumente.
Erstellen Sie ein Parameterpaket, das aus Ganzzahlen besteht
std::integer_sequence
selbst geht es um das Halten einer Folge von Ganzzahlen, die in ein Parameterpaket umgewandelt werden können. Sein primärer Wert ist die Möglichkeit, "Factory" Klassenvorlagen zu erstellen, die diese Sequenzen erstellen:
#include <iostream>
#include <initializer_list>
#include <utility>
template <typename T, T... I>
void print_sequence(std::integer_sequence<T, I...>) {
std::initializer_list<bool>{ bool(std::cout << I << ' ')... };
std::cout << '\n';
}
template <int Offset, typename T, T... I>
void print_offset_sequence(std::integer_sequence<T, I...>) {
print_sequence(std::integer_sequence<T, T(I + Offset)...>());
}
int main() {
// explicitly specify sequences:
print_sequence(std::integer_sequence<int, 1, 2, 3>());
print_sequence(std::integer_sequence<char, 'f', 'o', 'o'>());
// generate sequences:
print_sequence(std::make_index_sequence<10>());
print_sequence(std::make_integer_sequence<short, 10>());
print_offset_sequence<'A'>(std::make_integer_sequence<char, 26>());
}
Die Funktionsvorlage print_sequence()
verwendet beim Erweitern der Ganzzahlsequenz eine std::initializer_list<bool>
, um die Reihenfolge der Auswertung zu gewährleisten und keine ungenutzte [array] print_sequence()
erstellen.
Verwandeln Sie eine Folge von Indizes in Kopien eines Elements
Durch Erweitern des Parameterpakets von Indizes in einem Kommaausdruck um einen Wert wird eine Kopie des Werts für jeden der Indizes erstellt. Leider glauben gcc
und clang
dass der Index keine Auswirkung hat und warnen ( gcc
kann zum Schweigen gebracht werden, indem der Index für void
):
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <string>
#include <utility>
template <typename T, std::size_t... I>
std::array<T, sizeof...(I)> make_array(T const& value, std::index_sequence<I...>) {
return std::array<T, sizeof...(I)>{ (I, value)... };
}
template <int N, typename T>
std::array<T, N> make_array(T const& value) {
return make_array(value, std::make_index_sequence<N>());
}
int main() {
auto array = make_array<20>(std::string("value"));
std::copy(array.begin(), array.end(),
std::ostream_iterator<std::string>(std::cout, " "));
std::cout << "\n";
}