Tupel Type/Instanz per Template-Funktion erzeugen/instanzieren? geht das?
-
Ich würde gerne wissen ob man den mit "====> FRAGE" markierten von Hand ausgeschriebenen Code auch mit Templates machen kann - ich kenne mich leider noch nicht so gut aus mit Variadic Templates, Expression Folding, etc.
Es geht um die Adaption von Methoden-Schnittstellen auf eine Abstraktes Interface - in diesem kompilierbaren Beispiel sieht man das aber nicht wirklich - das Beispiel ist hoffentlich klein genug und trotzdem ausreichend um mein Problem zu verstehen
Würde mich über Tips oder Lösungsansätze freue - und Nein! Es ist keine Hausaufgabe
Online Kompilieren/Ausführen: https://onlinegdb.com/rJGBenZN4
Update: mal einen Versuch eingebaut um Frage 2 zu beantworten - ich scheitere kläglich
// aktuelle VS2017 Version, oder GCC 8.2, C++14 oder C++17 waere moeglich #include <tuple> #include <vector> #include <cassert> template<typename Value> struct in_parameter_t { in_parameter_t(void* value) {} }; template<typename Value> struct out_parameter_t { out_parameter_t(void* value) {} }; template<typename Value> struct inout_parameter_t { inout_parameter_t(void* value) {} }; template<typename ValueType> struct parameter_type_t {}; template<> struct parameter_type_t<int> { using type = in_parameter_t<int>; }; template<> struct parameter_type_t<int&> { using type = inout_parameter_t<int>; }; using parameter_t = std::vector<void*>; /* // Versuch Frage 2 zu beantworten - aber ausser viele viele Varianten von Kompilefehler komme ich da nicht weiter namespace detail { template <typename TupleType_TP, size_t... Indices_TPs> auto get_parameter(parameter_t& parameter, std::index_sequence<Indices_TPs...>) { //return TupleType_TP(parameter[Indices_TPs]...); return TupleType_TP({ nullptr, nullptr }); } } template <typename... Types_TPs> auto get_parameter(parameter_t& parameter) { return detail::get_parameter<std::tuple<Types_TPs...>>(parameter, std::index_sequence_for<Types_TPs...>()); } */ int main() { //------ // Kompilezeit-Parameter // Methoden-Parameter-Typen using native_parameter_types = std::tuple<int,int&>; //------ // Laufzeit-Parameter int p0 = 0; int p1 = 0; parameter_t parameter{&p0, &p1}; // muss ein std::vector sein (std::array ist zu fix) // zur Laufzeit garantiert das zu jedem native_parameter_types[x] ein parameter[x] existiert assert(parameter.size() == std::tuple_size<native_parameter_types>::value); //------ // hier kommen mein Fragen // aus dem nativen typ einen adapter typ erzeugen using parameter_types_t = std::tuple < parameter_type_t<std::tuple_element<0, native_parameter_types>::type>::type, parameter_type_t<std::tuple_element<1, native_parameter_types>::type>::type >; //====> FRAGE 1: geht das auch mit einer Template-Funktion? //so in der Art? //using parameter_types_t = get_parameter_types<native_parameter_types>::types; // die adapter mit dem parameter-pointer instanzieren auto p = parameter_types_t ( parameter[0], parameter[1] ); //====> FRAGE 2: geht das auch mit einer Template-Funktion? //so in der Art? //auto p = get_parameter<parameter_types_t>(parameter); return 0; }
-
Setz dich doch mal mit variadic templates auseinander, und insbesondere index Listen. Dann werden die Loesungen fuer dein Problem recht offensichtlich erscheinen.
-
ein Beispiel im Internet gefunden das schon mal einen gute Orientierung gibt
die Frage 3 kann ich damit schon beantworten
namespace detail { template <typename TupleType_TP, size_t... Indices_TPs, typename Callable_TP> void ForEachTupleElementImpl(TupleType_TP&& t, std::index_sequence<Indices_TPs...>, Callable_TP f) { #if 0 // C++14 trick using SinkHole_TP = int[]; (void)SinkHole_TP { 0, // This makes the array at least 1 element (0 elem arrays are ill-formed) ((void)(f(std::get<Indices_TPs>(t))), 0)... }; #else // in VS2017 und LLVM muss der C++17 Standard aktiviert werden sonst kompiliert das nicht // In C++17, this can be done with a fold expression (new language construct) instead: (f(std::get<Indices_TPs>(t)), ...); #endif } } template <typename... Types_TPs, typename Callable_TP> void ForEachTupleElement(std::tuple<Types_TPs...>& t, Callable_TP f) { detail::ForEachTupleElementImpl(t, std::index_sequence_for<Types_TPs...>(), f); } // damit kann ich schon mal die Template-Funktion aus Frage 3 realisieren // aus // std::get<0>(p).load(); // std::get<1>(p).load(); // wird // load_parameter(p); template<typename NativeTypesTuple_TP> void load_parameter(NativeTypesTuple_TP& adapter) { ForEachTupleElement(adapter, [](auto&& e) { e.load(); }); }
-
Alle Fragen beantwortet - Danke für die Tips