Liebe Internet Menschen, aufzurufenC++ eine Template-Parameter Packung mit mehreren Templat Funktionen
Ich bin derzeit eine Variante Klasse in C++ 14 und benötigen das Schreiben eine Template-Funktion für jedes Element in den Parametern nennen Pack. Nach einigem Suchen stieß ich auf this Seite, die das folgende Beispiel kennzeichnet.
template<typename... Ts> void func(Ts... args){
const int size = sizeof...(args) + 2;
int res[size] = {1,args...,2};
// since initializer lists guarantee sequencing, this can be used to
// call a function on each element of a pack, in order:
int dummy[sizeof...(Ts)] = { (std::cout << args, 0)... };
}
Ich habe dieses kleine Beispiel erstellt, das demonstriert, was ich zu erreichen versuche.
#include <iostream>
template<typename Ta, typename Tb> struct TypeCmp
{
static constexpr bool Value = false;
};
template<typename T> struct TypeCmp<T, T>
{
static constexpr bool Value = true;
};
template<typename T, typename... Ts> struct TypeIdCounter;
template<typename T> struct TypeIdCounter<T>
{
static constexpr size_t Value = 1;
};
template<typename T, typename Tcur, typename... Ts> struct TypeIdCounter<T, Tcur, Ts...>
{
static constexpr size_t Value = sizeof(Tcur)+(TypeCmp<T, Tcur>::Value ? 0 : TypeIdCounter<T, Ts...>::Value);
};
template<typename... Ts> struct TypeHolder
{
template<typename T> struct Info
{
static constexpr size_t Id = TypeIdCounter<T, Ts...>::Value;
static constexpr size_t Size = sizeof(T);
static void Print(size_t id)
{
if (Id == id)
{
std::cout << "Type::Id = " << Id << std::endl;
std::cout << "Type::Size = " << Size << std::endl;
}
}
};
template<typename T> TypeHolder(const T& value) : id(Info<T>::Id)
{
/* copy value to container */
}
void Print() const
{
int dummy[] = {(Info<Ts>::Print(id), 0)...};
if (dummy[0])
{
/* dummy test needed! */
}
}
size_t id;
};
struct Foo
{
std::string name;
int age;
};
typedef TypeHolder<int, long long, bool, Foo> MyTypes;
int main(int argc, char* args[])
{
std::cout << "Id(int): " << MyTypes::Info<int>::Id << std::endl;
std::cout << "Id(bool): " << MyTypes::Info<bool>::Id << std::endl;
std::cout << "Id(Foo): " << MyTypes::Info<Foo>::Id << std::endl;
MyTypes types(true);
types.Print();
return 0;
}
Das oben aufgelistete Programm generiert die folgende Ausgabe.
Id(int): 4
Id(bool): 13
Id(Foo): 53
Type::Id = 13
Type::Size = 1
Wie immer kompilieren ich meinen Code mit den -Wall -Werror
Fahnen. Also die if (dummy[0])...
Bedingung wird benötigt, sonst bekomme ich einen unused variable 'dummy'
Fehler.
Ich bin total ahnungslos, warum int dummy[] = {(Info<Ts>::Print(id), 0)...};
scheint zu arbeiten, da Info::Print
ist eine void-Methode. Könnte mich jemand aufklären und erklären, warum das funktioniert? Und gibt es eine Möglichkeit, den int dummy[] = {(...)}; if (dummy[0]);
Trick zu verhindern, ohne -Wall -Werror
fallen zu lassen?
Ich habe versucht, nach einer Erklärung zu suchen, aber da ich keine Ahnung habe, wie diese Konstruktion überhaupt heißt, ist es nicht einfach, etwas zu finden.
Sie sollten 'int dummy [Größe von ... (Ts)] = {(void (std :: cout << args), 0) ...} sagen;' wenn Sie diesen Trick verwenden, um unerwünschte ADL zu vermeiden und Operator Überlastung Nebenwirkungen –
Ist die Zeile 'Int res [Größe] ...' versehentlich eingefügt? – feersum
Schlüsselwörter: 'Komma Operator', 'Parameter Packs'. – feersum