Potrzebujesz szablonu maszyny meta-programowania do osiągnięcia tego.
Najprostszym sposobem na wywołanie argumentu jest wykorzystanie rozszerzenia paczek dla wyrażeń, które zawierają spakowaną sekwencję liczb całkowitych z liczb całkowitych. Aby zbudować taką sekwencję, niezbędna jest maszyna szablonowa (zobacz także uwagę na końcu tej odpowiedzi, aby uzyskać więcej informacji na temat propozycji standaryzacji takiej sekwencji).
Przypuśćmy mieć klasę (szablon) index_range
która zamyka szereg kompilacji liczb całkowitych [m, n) i klasy (szablon) index_list
który obudowuje listę kompilacji liczb całkowitych, to jak należałoby użyć im:
template<typename T, typename... Args>
struct foo
{
tuple<Args...> args;
// Allows deducing an index list argument pack
template<size_t... Is>
T gen(index_list<Is...> const&)
{
return T(get<Is>(args)...); // This is the core of the mechanism
}
T gen()
{
return gen(
index_range<0, sizeof...(Args)>() // Builds an index list
);
}
};
i tu jest możliwa realizacja index_range
i index_list
:
//===============================================================================
// META-FUNCTIONS FOR CREATING INDEX LISTS
// The structure that encapsulates index lists
template <size_t... Is>
struct index_list
{
};
// Collects internal details for generating index ranges [MIN, MAX)
namespace detail
{
// Declare primary template for index range builder
template <size_t MIN, size_t N, size_t... Is>
struct range_builder;
// Base step
template <size_t MIN, size_t... Is>
struct range_builder<MIN, MIN, Is...>
{
typedef index_list<Is...> type;
};
// Induction step
template <size_t MIN, size_t N, size_t... Is>
struct range_builder : public range_builder<MIN, N - 1, N - 1, Is...>
{
};
}
// Meta-function that returns a [MIN, MAX) index range
template<unsigned MIN, unsigned MAX>
using index_range = typename detail::range_builder<MIN, MAX>::type;
zauważyć również, że istnieje interesting proposal przez Jonathan Wakelystandaryzuje szablon klasy int_seq
, który jest czymś bardzo podobnym do tego, co nazwałem index_list
tutaj.
nie próbowałem tego ale wygląda na to, że masz tam jeden błąd: ustawiasz 'MAX' na' sizeof ... (Args) - 1', chociaż to maksimum jest wykluczone z listy.W przeciwnym razie dziękuję za wspaniałą odpowiedź, ponieważ bardzo wyraźnie wyjaśnia poszczególne kroki. – MvG
@MvG: Dokładnie! Przepraszam za to, dobry połów. –
Przednia deklaracja głównego szablonu jest bezcelowa i dezorientująca. Po prostu zdefiniuj "Krok indukcyjny" pierwszy. – Nikolai