2

Pre-DramatischeAliasing ein Template-Parameter Pack

Hallo, vielleicht ist diese Frage ein Duplikat, aber ich bin relativ neu in Template-Programmierung und ich bin wirklich nicht in der Lage ein einfache und kurz zu finden Lösung (-> nur finden Megabyte von "roxxor-Vorlage-Magie" die ich nicht verstehe) passend zu meinem konkreten und einfachen Problem und so fühle ich mich ein wenig verloren jetzt.

Vorinformationen

ich ein "type_container" als Template-Parameter für eine Klasse verwenden möchten. Der Container ist eine einfache Struktur, die auch einige typedefs für Vorlagen-Parameterpakete enthalten sollte.

Frage: (bezogen auf das Beispiel unten)

Wie kann ich definieren und alias der Typ-Listen in den Container-Struktur und wie kann ich auf und leiten sie an die benötigten Einheiten in der Fabrikklasse? (Kein Schub und nur C++ 11/14/17)

Beispiel: (Wäre kompilieren, wenn ich eine Lösung kennen würde)

#include <map> 
#include <vector> 
#include <string> 
#include <stack> 

struct MY_TYPE_CONTAINER 
{ 
    using TYPE_MAP   = std::map<int, int>; 
    using TYPE_VECTOR   = std::vector<double>; 
    using PARAMETER_PACK1 = //? -> ...T -> int, std::stack<int>, int 
    using PARAMETER_PACK2 = //? -> ...T -> double, int, std::string 
}; 

template <typename TYPES> 
struct Factory 
{ 
    typename TYPES::TYPE_MAP      m_map; 
    typename TYPES::TYPE_VECTOR     m_vector; 
    typename std::tuple<TYPES::PARAMETER_PACK1...> m_tuple; 
    typename std::tuple<std::shared_ptr<TYPES::PARAMETER_PACK1>...> m_tuple2; 
    void handlePack2(TYPES::PARAMETER_PACK2... args) { } 
}; 


int main() 
{ 
    Factory<MY_TYPE_CONTAINER> oStaticFactory; 
    oStaticFactory.handlePack2(2.0, 1, "hi"); 
    return 0; 
} 

Strom (? Best) erarbeitet Lösung (übersetzbar) (Basierend auf John Zwinck Antwort)

#include <map> 
#include <vector> 
#include <string> 
#include <stack> 
#include <memory> 

struct MY_TYPE_CONTAINER 
{ 
    using TYPE_MAP     = std::map<int, int>; 
    using TYPE_VECTOR     = std::vector<double>; 
    using PARAMETER_PACK1    = std::tuple<int, std::stack<int>, int>; 
    using PARAMETER_SHARED_PTR_PACK_1 = std::tuple<std::shared_ptr<int>, std::shared_ptr<std::stack<int>>, std::shared_ptr<int>>; 
    using PARAMETER_PACK2    = std::tuple<double, int, std::string>; 
}; 

template <typename TYPES> 
class Factory 
{ 
    typename TYPES::TYPE_MAP     m_map; 
    typename TYPES::TYPE_VECTOR     m_vector; 
    typename TYPES::PARAMETER_PACK1    m_tuple; 
    typename TYPES::PARAMETER_SHARED_PTR_PACK_1 m_tuple2; 

    void handlePack2Impl(typename TYPES::PARAMETER_PACK2 tup) {}; 

public: 
    template <typename... Args> 
    void handlePack2(Args... args) { handlePack2Impl(std::make_tuple(args...)); } 
}; 

int main() 
{ 
    Factory<MY_TYPE_CONTAINER> oStaticFactory; 
    oStaticFactory.handlePack2(2.0, 1, "hi"); 
    return 0; 
} 
+0

C++ 17, 14 oder 11? – Yakk

+0

Hinzugefügt zu meiner Frage. – BrandonCPP08

+0

Die Handhabung dieses Typenpakets zum Deklarieren von Datenelementen ist relativ einfach, aber [Sie werden sich die Mitgliederfunktionen zunutze machen] (https://stackoverflow.com/questions/47473986/declaring-a-member-function-with -a-typedef-coming-from-a-metafunction) ... – Quentin

Antwort

2

Sie können tatsächlich nutzen tuple:

using PARAMETER_PACK1 = std::tuple<int, std::stack, int>; 
using PARAMETER_PACK2 = std::tuple<double, int, std::string>; 

typename TYPES::PARAMETER_PACK1 m_tuple; 

Dann sind Sie mit einem Problem links - wie so etwas zu erklären:

void handlePack2(TYPES::PARAMETER_PACK2... args); 

Vielleicht:

void handlePack2Impl(typename TYPES::PARAMETER_PACK2 tup); 

template <typename... Args> 
void handlePack2(Args... args) { handlePack2Impl(std::make_tuple(args...)); } 

Für weitere Ideen, beginnt hier: Tuple to parameter pack (aber Vorsicht, es gibt Template-Meta-Programmierung!

+2

C++ 17 fügt ['std :: apply '] (http://en.cppreference.com/w/cpp/utility/apply) hinzu wird auch die Arbeit tun, ein Tupel auf eine Reihe von Parametern zu erweitern. –

+0

@DrewDormann: Wir konvertieren eine Reihe von Argumenten in ein Tupel, nicht umgekehrt. Ich bin mir nicht sicher, wie "std :: apply" zutrifft. –

+0

@John Zwinck: Das heißt, ich kann nicht vermeiden, diese Member-Typen der Fabrik im Typ-Container zu spezifizieren?Ich habe den Code mit einem anderen Mitglied m_tuple2 erweitert. Wie kann ich mit dieser Art von Mitglied umgehen? Soll ich diesen Full-Type auch auf den Typ-Container übertragen? – BrandonCPP08

1

Grundsätzlich können Sie das nicht tun. Die nächste Sache, die Sie tun können, ist zu speichern std::tuple<type, type, type> (oder Ihre eigenen variadic_class<type, type, type>, die leeren Körper haben können) und dann die Liste zurück durch kleine Vorlagen Magie