Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » C++0x: Alle Funktionsadressen einer template-Funktion ermitteln

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
13.03.2010, 17:05 Uhr
Prog



Hi, ich hab mal wieder ne Frage bezüglich templates.

Sinngemäß habe ich eine Templateklasse mit einer beliebigen Zahl von Typparametern. Diese einhält eine Templatefuntion, welche einen (integer) Index als Templateparamter erhält und daraus dementsprechend den Typparameter als Rückgabewert zuordnet. Als Quellcode sieht das ungefähr so aus:


C++:
template < typename ... Types >
struct Klasse{
    template < ::std::size_t Index > struct Result{
        typedef typename ::std::tuple_element< Index, ::std::tuple< Types ... > >::type type;
    };

    template < ::std::size_t Index >
    typename Result< Index >::type funktion(){
        // Zum testen beispielsweise:
        return static_cast< typename Result< Index >::type >(Index);
    }
};



Was ich im Endeffekt benötige ist ein std::tuple das für alle Klasse< Types ... >::funktion's die Adressen enthält. Manuell lässt sich das leicht realisieren, wie mein nächstes Beispiel zeigt. Ich benutze hierbei ein Hilfstemplate "make_function_pointer" um die Syntax nicht unnötig zu verkomplizieren.


C++:
// Type - Klassentyp
// ReturnType - Funktionsrückgabetyp
// Parameters - Eventuelle Funktionsparameter (ist hier nicht der Fall)
template < typename Type, typename ReturnType, typename ... Parameters >
struct make_function_pointer{
    typedef ReturnType(Type::*type)(Parameters ...);
};

int main(){
    Klasse<char, int, int, short> object;

    ::std::tuple<
        make_function_pointer<
            Klasse<char, int, int, short>,
            Klasse<char, int, int, short>::Result< 0 >::type
        >::type,
        make_function_pointer<
            Klasse<char, int, int, short>,
            Klasse<char, int, int, short>::Result< 1 >::type
        >::type,
        make_function_pointer<
            Klasse<char, int, int, short>,
            Klasse<char, int, int, short>::Result< 2 >::type
        >::type,
        make_function_pointer<
            Klasse<char, int, int, short>,
            Klasse<char, int, int, short>::Result< 3 >::type
        >::type
    > result_tuple(
        &Klasse<char, int, int, short>::funktion< 0 >,
        &Klasse<char, int, int, short>::funktion< 1 >,
        &Klasse<char, int, int, short>::funktion< 2 >,
        &Klasse<char, int, int, short>::funktion< 3 >
    );

    // Ausgabe
    std::cout << static_cast< int >(
        (object.*::std::get< 0 >(result_tuple))()
    ) << std::endl;
    std::cout << static_cast< int >(
        (object.*::std::get< 1 >(result_tuple))()
    ) << std::endl;
    std::cout << static_cast< int >(
        (object.*::std::get< 2 >(result_tuple))()
    ) << std::endl;
    std::cout << static_cast< int >(
        (object.*::std::get< 3 >(result_tuple))()
    ) << std::endl;
}



Da ich dieses std::tuple innerhalb einer Templatefunktion ermitteln will die eine Klasse< ... >-Objekt bekommt, fällt die manuelle Erzeugung aus, da ich keine direkt nutzbare Information über die Anzahl der Templateparameter habe. Außerdem halte ich die Syntax sowieso für zu kompliziert.

Mein Ansatz sah so aus, das ich einem weiterem Template die Template-ID (nennt man das so?) von "Klasse< Types ... >::funktion" übergebe. Das würde dann etwa so aussehen:


C++:
template < template < ::std::size_t > class funktion_id >
struct WasAuchImmer{};



Wenn ich nun versuche den ensprechenden Typ zu erzeugen, beschwert sich der Compiler, das es sich beim übergeben Parameter nicht um ein Klassentemplate handelt.


C++:
template < template < ::std::size_t > class funktion_id >
struct WasAuchImmer{};

int main(){
    WasAuchImmer< Klasse<char, int, int, short>::funktion >;
}



Gibt es eine Möglichkeit WasAuchImmer die entsprechende "Funktionsmenge" zu übergeben, so das ich darin das entsprechende std::tuple ermitteln kann?

Die Syntax, die ich letztlich zum erstellen des std::tuple's nutzen würde, sollte ungefähr folgende sein:


C++:
make_address_tuple<
    Klasse< Types ... >,
    Klasse< Types ... >::funktion
>(
    object_von_Klasse_Types_ppp
);

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
13.03.2010, 18:25 Uhr
0xdeadbeef
Gott
(Operator)


Du hast da keine Templateklasse und keine Templatefunktion. Ich wüsste auch nicht, was das sein sollte. Du hast stattdessen eine Klassentemplate und eine Funktionstemplate bzw. Klassenvorlage und Funktionsvorlage, aus der Klassen bzw. Funktionen konkretisiert werden können, und solche Vorlagen haben keine Speicheradresse - sie sind zur Laufzeit nämlich gar nicht mehr da.

Dementsprechend muss ich ein bisschen raten, was du eigentlich willst. Also, die Anzahl variadischer Template-Parameter kriegst du etwa so gezählt:

C++:
template<typename...> struct vt_count;
template<typename T, typename... U> struct vt_count<T, U...> {
  static std::size_t const val = vt_count<U...>::val + 1;
};
template<typename T> struct vt_count<T> { static std::size_t const val = 1; };


eigentlich müsste es auch so gehen:

C++:
template<typename T, typename... U> struct vt_count {
  static std::size_t const val = vt_count<U...>::val + 1;
};
template<typename T> struct vt_count<T> { static std::size_t const val = 1; };


...aber das hat der gcc noch nicht implementiert, deshalb der workaround mit der Spezialisierung. Auf ähnliche Weise kannst du den Tupeltyp zusammensetzen, etwa - jetzt mal so hingeschludert -

C++:
template<typename tuple_t, typename atv_t> struct append_to_tuple_type;
template<typename... T, typename V> struct append_to_tuple_type<std::tuple<T...>, V> {
  typedef std::tuple<T..., V> type;
};


Damit kannst du dann in einer Art Schleife den Tupeltyp zusammensetzen. Die Methodenzeiger wirst du aber wohl einzeln in das Tupel schreiben müssen.

Hilft dir das erstmal weiter?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
13.03.2010, 18:50 Uhr
0xdeadbeef
Gott
(Operator)


Nachtrag: Ich hab mal ein bisschen rumgespielt:

C++:
#include <cstddef>
#include <iostream>
#include <tuple>
#include <typeinfo>

template<typename...> struct vt_count;
template<typename T, typename... U> struct vt_count<T, U...> {
  static std::size_t const val = vt_count<U...>::val + 1;
};

template<typename T> struct vt_count<T> { static std::size_t const val = 1; };

template<typename tuple_t, typename atv_t> struct append_to_tuple_type;
template<typename... T, typename V> struct append_to_tuple_type<std::tuple<T...>, V> {
  typedef std::tuple<T..., V> type;
};

template<std::size_t pos, typename... T> struct vt_deref;
template<std::size_t pos, typename T, typename... U> struct vt_deref<pos, T, U...> {
  typedef typename vt_deref<pos - 1, U...>::type type;
};
template<typename T, typename... U> struct vt_deref<0, T, U...> { typedef T type; };

template<std::size_t pos, typename... T> struct assemble_tuple_type_be {
  typedef typename append_to_tuple_type<typename assemble_tuple_type_be<pos - 1, T...>::type,
                    typename vt_deref              <pos - 1, T...>::type>::type type; // <--
};

template<typename... T> struct assemble_tuple_type_be<1, T...> {
  typedef std::tuple<typename vt_deref<0, T...>::type> type; // <--
};

template<typename... T> struct assemble_tuple_type {
  typedef typename assemble_tuple_type_be<vt_count<T...>::val, T...>::type type;
};

int main() {
  std::cout << typeid(assemble_tuple_type<int, std::ostream, short, std::istream, long>::type).name() << std::endl;
}


Im Grunde musst du nur an den markierten Stellen deine make_function_pointer-Vorlage reinschreiben, und kannst dann in Klasse typename assemble_tuple_type<Types...>::type als Tupeltyp benutzen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
13.03.2010, 19:33 Uhr
0xdeadbeef
Gott
(Operator)


Und nochmal nachgelegt:

C++:
////////////////////////////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include <iostream>
#include <tuple>
#include <typeinfo>
#include <utility>

template<typename   , typename   > struct append_to_tuple_type;
template<             typename...> struct assemble_tuple_type;
template<std::size_t, std::size_t, typename...> struct init_func_tuple;
template<             typename...> struct make_function_pointer;
template<             typename...> struct vt_count;
template<std::size_t, typename...> struct vt_deref;

template < typename ... Types >
struct Klasse {
  template < ::std::size_t Index > struct Result{
    typedef typename ::std::tuple_element< Index, ::std::tuple< Types ... > >::type type;
  };

  template < ::std::size_t Index >
  typename Result< Index >::type funktion(){
    // Zum testen beispielsweise:
    return static_cast< typename Result< Index >::type >(Index);
  }

  typedef typename assemble_tuple_type<Types...>::type func_tuple_t;

  static func_tuple_t func_tuple() {
    func_tuple_t f;
    init_func_tuple<0, vt_count<Types...>::val, Types...>::doit(f);
    return f;
  }
};

template<std::size_t pos, std::size_t max, typename... T> struct init_func_tuple {
  static void doit(typename Klasse<T...>::func_tuple_t &f) {
    init_func_tuple<pos + 1, max, T...>::doit(f);
    std::get<pos>(f)
      = &Klasse<T...>::template funktion<pos>;
  }
};

template<std::size_t pos, typename... T> struct init_func_tuple<pos, pos, T...> {
  static void doit(typename Klasse<T...>::func_tuple_t &f) { }
};

template < typename Type, typename ReturnType, typename ... Parameters >
struct make_function_pointer<Type, ReturnType, Parameters...> {
    typedef ReturnType(Type::*type)(Parameters ...);
};

template<typename T, typename... U> struct vt_count<T, U...> {
  static std::size_t const val = vt_count<U...>::val + 1;
};

template<typename T> struct vt_count<T> { static std::size_t const val = 1; };

template<typename... T, typename V> struct append_to_tuple_type<std::tuple<T...>, V> {
  typedef std::tuple<T..., V> type;
};

template<std::size_t pos, typename T, typename... U> struct vt_deref<pos, T, U...> {
  typedef typename vt_deref<pos - 1, U...>::type type;
};
template<typename T, typename... U> struct vt_deref<0, T, U...> { typedef T type; };

template<std::size_t pos, typename... T> struct assemble_tuple_type_be {
  typedef typename
  append_to_tuple_type<typename assemble_tuple_type_be<pos - 1, T...>::type,
                       typename make_function_pointer<Klasse           <         T...>,
                                                      typename vt_deref<pos - 1, T...>::type
                                                      >::type
                       >::type type;
};

template<typename... T> struct assemble_tuple_type_be<1, T...> {
  typedef std::tuple<typename make_function_pointer<Klasse           <   T...>,
                                                    typename vt_deref<0, T...>::type>::type> type;
};

template<typename... T> struct assemble_tuple_type {
  typedef typename assemble_tuple_type_be<vt_count<T...>::val, T...>::type type;
};

int main() {
  typedef Klasse<int, short, long> kt;
  typedef kt::func_tuple_t tt;

  std::cout << typeid(tt).name() << std::endl
            << typeid(std::tuple_element<0, tt>::type).name() << std::endl
            << typeid(std::tuple_element<1, tt>::type).name() << std::endl
            << typeid(std::tuple_element<2, tt>::type).name() << std::endl;

  auto x = kt::func_tuple();
  kt k;

  std::cout << (k.*std::get<0>(x))() << std::endl
            << (k.*std::get<1>(x))() << std::endl
            << (k.*std::get<2>(x))() << std::endl;
}


Templates sind toll!
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 13.03.2010 um 19:40 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
13.03.2010, 19:51 Uhr
Prog



So, ich hab meinen Abendspaziergang beendet und danke dir für deine Bemühungen. :-) Es wird sicher ein paar Minuten dauern, bis ich mich da durchgearbeitet hab.

Eine Frage hab ich aber bereits: Ist dein "vt_count< Types ... >::val" nicht mit "sizeof...( Types )" identisch? Wenn ja lassen sich die Spezialisierungen auch einsparen.


C++:
template<typename ... T> struct vt_count { static std::size_t const val = sizeof...(T); };



PS:

Templateklasse und Templatefunktion sind meine verhunzten Versionen der Worte Klassentemplate und Funktionstemplate. ;-)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
13.03.2010, 20:03 Uhr
0xdeadbeef
Gott
(Operator)


Ah. Scheint so; ich hab es bloß nicht gewusst.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
13.03.2010, 20:52 Uhr
Prog



Schön, das bringt mich schon ein gutes Stückchen weiter. :-)

Das Problem dabei ist, das ich innerhalb von "init_func_tuple" immer noch wissen muss, wie das benötigte Funktionstemplate konkret heißt. Besser wäre es, wenn ich "init_func_tuple" diesen Namen irgendwie beim "Aufruf" (Wie ist da das richtige Wort?) zugänglich machen könnte. Ansonsten müsste ich für jedes Funktionstemplate ein solches Template schreiben und das ist natürlich nicht sonderlich bequem.

Die entsprechende Klasse auf zugänglich zu machen ist kein Problem. Ich hab den Code mal soweit umgeschrieben das er (bis auf die Sache mit dem Funktionstemplate) meinen Vorstellungen entspricht.


C++:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include <iostream>
#include <tuple>
#include <typeinfo>
#include <utility>

template<typename   , typename   > struct append_to_tuple_type;
template<             typename...> struct assemble_tuple_type;
template<std::size_t, std::size_t, template <typename...> class, typename...> struct init_func_tuple;
template<             typename...> struct make_function_pointer;
template<             typename...> struct vt_count;
template<std::size_t, typename...> struct vt_deref;

template < typename ... Types >
struct Klasse {
  template < ::std::size_t Index > struct Result{
    typedef typename ::std::tuple_element< Index, ::std::tuple< Types ... > >::type type;
  };

  template < ::std::size_t Index >
  typename Result< Index >::type funktion(){
    // Zum testen beispielsweise:
    return static_cast< typename Result< Index >::type >(Index);
  }
};

template <typename ...T>
struct func_tuple_t {
  typedef typename assemble_tuple_type<T...>::type type;
};

template <template <typename...> class C, typename ...T>
typename func_tuple_t<T...>::type func_tuple() {
  typename func_tuple_t<T...>::type f;
  init_func_tuple<0, vt_count<T...>::val, C, T...>::doit(f);
  return f;
}

template<std::size_t pos, std::size_t max, template <typename...> class C, typename... T> struct init_func_tuple {
  static void doit(typename func_tuple_t<T...>::type &f) {
    init_func_tuple<pos + 1, max, C, T...>::doit(f);
    std::get<pos>(f)
      = &C<T...>::template funktion<pos>;
  }
};

template<std::size_t pos, template <typename...> class C, typename... T> struct init_func_tuple<pos, pos, C, T...> {
  static void doit(typename func_tuple_t<T...>::type &f) { }
};

template < typename Type, typename ReturnType, typename ... Parameters >
struct make_function_pointer<Type, ReturnType, Parameters...> {
  typedef ReturnType(Type::*type)(Parameters ...);
};

template<typename... T> struct vt_count {
  static std::size_t const val = sizeof...(T);
};

template<typename... T, typename V> struct append_to_tuple_type<std::tuple<T...>, V> {
  typedef std::tuple<T..., V> type;
};

template<std::size_t pos, typename T, typename... U> struct vt_deref<pos, T, U...> {
  typedef typename vt_deref<pos - 1, U...>::type type;
};
template<typename T, typename... U> struct vt_deref<0, T, U...> { typedef T type; };

template<std::size_t pos, typename... T> struct assemble_tuple_type_be {
  typedef typename append_to_tuple_type<typename assemble_tuple_type_be<pos - 1, T...>::type,
                    typename make_function_pointer<Klasse           <         T...>,
                                       typename vt_deref<pos - 1, T...>::type>::type>::type type;
};

template<typename... T> struct assemble_tuple_type_be<1, T...> {
  typedef std::tuple<typename make_function_pointer<Klasse           <   T...>,
                            typename vt_deref<0, T...>::type>::type> type;
};

template<typename... T> struct assemble_tuple_type {
  typedef typename assemble_tuple_type_be<vt_count<T...>::val, T...>::type type;
};

int main() {
  typedef Klasse<int, short, long, int> kt;
//   typedef func_tuple_t<int, short, long, int> tt;

  auto x = func_tuple<Klasse, int, short, long, int>();
  kt k;

  std::cout << (k.*std::get<0>(x))() << std::endl
        << (k.*std::get<1>(x))() << std::endl
        << (k.*std::get<2>(x))() << std::endl
        << (k.*std::get<3>(x))() << std::endl;

//   std::cout << typeid(tt).name() << std::endl
//         << typeid(std::tuple_element<0, tt>::type).name() << std::endl
//         << typeid(std::tuple_element<1, tt>::type).name() << std::endl
//         << typeid(std::tuple_element<2, tt>::type).name() << std::endl
//         << typeid(std::tuple_element<3, tt>::type).name() << std::endl;
}



Die auskommentierten Zeilen werden derzeit mit "incomplete type »std::tuple_element<"{0-3}"ul, func_tuple_t<int, short int, long int, int> >« used in nested name specifier" quittiert, aber dazu fällt dir sicher schneller was ein als mir, daher hab ich mich jetzt nicht darum gekümmert.

PS: Freut mich, das ich auch mal was wusste, das dir nicht bekannt war. Das bewahrt mein Selbstbewusstsein davor, endgültig im Keller zu verschwinden. ;-)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
13.03.2010, 21:16 Uhr
Prog



Ich muss noch mal korrigieren:


C++:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include <iostream>
#include <tuple>
#include <typeinfo>
#include <utility>

template<                                 typename, typename   > struct append_to_tuple_type;
template<template <typename...> class,              typename...> struct assemble_tuple_type;
template<std::size_t, std::size_t, template <typename...> class, typename...> struct init_func_tuple;
template<                                           typename...> struct make_function_pointer;
template<                                           typename...> struct vt_count;
template<                              std::size_t, typename...> struct vt_deref;

template < typename ... Types >
struct Klasse {
  template < ::std::size_t Index > struct Result{
    typedef typename ::std::tuple_element< Index, ::std::tuple< Types ... > >::type type;
  };

  template < ::std::size_t Index >
  typename Result< Index >::type funktion(){
    // Zum testen beispielsweise:
    return static_cast< typename Result< Index >::type >(Index);
  }
};

template <template <typename...> class C, typename ...T>
struct func_tuple_t {
  typedef typename assemble_tuple_type<C, T...>::type type;
};

template <template <typename...> class C, typename ...T>
typename func_tuple_t<C, T...>::type func_tuple() {
  typename func_tuple_t<C, T...>::type f;
  init_func_tuple<0, vt_count<T...>::val, C, T...>::doit(f);
  return f;
}

template<std::size_t pos, std::size_t max, template <typename...> class C, typename... T> struct init_func_tuple {
  static void doit(typename func_tuple_t<C, T...>::type &f) {
    init_func_tuple<pos + 1, max, C, T...>::doit(f);
    std::get<pos>(f)
      = &C<T...>::template funktion<pos>;
  }
};

template<std::size_t pos, template <typename...> class C, typename... T> struct init_func_tuple<pos, pos, C, T...> {
  static void doit(typename func_tuple_t<C, T...>::type &f) { }
};

template < typename Type, typename ReturnType, typename ... Parameters >
struct make_function_pointer<Type, ReturnType, Parameters...> {
  typedef ReturnType(Type::*type)(Parameters ...);
};

template<typename... T> struct vt_count {
  static std::size_t const val = sizeof...(T);
};

template<typename... T, typename V> struct append_to_tuple_type<std::tuple<T...>, V> {
  typedef std::tuple<T..., V> type;
};

template<std::size_t pos, typename T, typename... U> struct vt_deref<pos, T, U...> {
  typedef typename vt_deref<pos - 1, U...>::type type;
};
template<typename T, typename... U> struct vt_deref<0, T, U...> { typedef T type; };

template<template <typename...> class C, std::size_t pos, typename... T> struct assemble_tuple_type_be {
  typedef typename append_to_tuple_type<typename assemble_tuple_type_be<C, pos - 1, T...>::type,
                    typename make_function_pointer<C<T...>,
                                       typename vt_deref<pos - 1, T...>::type>::type>::type type;
};

template<template <typename...> class C, typename... T> struct assemble_tuple_type_be<C, 1, T...> {
  typedef std::tuple<typename make_function_pointer<C<T...>,
                            typename vt_deref<0, T...>::type>::type> type;
};

template<template <typename...> class C, typename... T> struct assemble_tuple_type {
  typedef typename assemble_tuple_type_be<C, vt_count<T...>::val, T...>::type type;
};

int main() {
  typedef Klasse<int, short, long, int> kt;
  typedef func_tuple_t<Klasse, int, short, long, int>::type tt;

  auto x = func_tuple<Klasse, int, short, long, int>();
  kt k;

  std::cout << (k.*std::get<0>(x))() << std::endl
        << (k.*std::get<1>(x))() << std::endl
        << (k.*std::get<2>(x))() << std::endl
        << (k.*std::get<3>(x))() << std::endl;

  std::cout << typeid(tt).name() << std::endl
        << typeid(std::tuple_element<0, tt>::type).name() << std::endl
        << typeid(std::tuple_element<1, tt>::type).name() << std::endl
        << typeid(std::tuple_element<2, tt>::type).name() << std::endl
        << typeid(std::tuple_element<3, tt>::type).name() << std::endl;
}



Das mit den Fehlermeldungen hat sich somit auch geklärt, func_tuple_t ist ja jetzt eine Templateklassen und nicht mehr der Typ selbst.

Dieser Post wurde am 13.03.2010 um 21:55 Uhr von Prog editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
13.03.2010, 22:03 Uhr
0xdeadbeef
Gott
(Operator)


Ist das ganze jetzt eigentlich mehr Spielerei zu Übungszwecken, oder brauchst du das konkret für etwas? Dinge dieser Art sieht man in Produktionscode eher selten, weil sie nicht jeder schreiben kann und sie dementsprechend schwer zu warten sind.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
13.03.2010, 23:17 Uhr
Prog



Ja und nein.

Ich bin seit einiger Zeit dabei, mir eine Bibliothek mit nützlichen Funktionen und Klassen zusammenzustellen. Was davon letztlich wirklich zum Einsatz kommt ist noch nicht sicher. Natürlich lässt sich das ganze für einen konkreten Fall auch immer einfacher lösen, aber die Lösung funktioniert dann eben auch nur für diesen Fall.

Das hier geschilderte Problem soll mir bei folgendem helfen:

Ich will auf einfache Weise für alle Elemente eines Tuples eine beliebige Funktion aufrufen. Das Tuple besteht dabei beispielsweise aus Vectoren mit unterschiedlichem Typ. Das funktioniert auch bereits für Funktionen mit beliebigem Rückgabewert und beliebigen Parametern. Ich übergebe dabei (für das Beispiel mit den Vectoren) folgendes:

1. Ein Tuple mit den Vector-Objekten
2. Ein Tuple mit den Funktionsadressen
n. Der (n-2)te Paramter der Funktion

Die Parameter können ihrerseits Tuple aus Parametern sein, sie müssen dann als parameter_list(ParameterTuple) übergeben werden. In diesem Fall variieren also die Objekttypen, während die Funktionen innerhalb der Objekttypen immer gleich sind (bitte nicht wörtlich nehmen). Ein solcher Aufruf lässt sich leicht mittels variadic templates erzeugen.

Nun habe ich aber eine Templateklassen welche intern mit einem Tuple arbeiten und nach außen einige mit Index versehen Funktionen bereitstellt. Beim normalen arbeiten mit der Klasse werden die Indizes durch ein enum realisiert, was die Lesbarkeit des Code gewährleistet. Es ist aber schwierig, alle diese Funktionen aufzurufen.

Wenn ich nun ein Tuple mit allen Funktionsadressen erzeuge, kann die eben beschriebene Funktion die nötigen Aufrufe sofort durchführen. Aber dieses Tuple zu erzeugen ist einigermaßen Komplex, ich brauche etwas das leicht Anwendbar und Verständlich ist.

Solange ein solches "Modul" keine Fehler enthält, muss es nach der Fertigstellung nicht mehr geändert werden, sondern nur noch eingesetzt. Dabei beschleunigt es das schreiben von Code erheblich und sorgt gleichzeitig dafür, dass der Code leicht zu lesen und somit zu warten ist. Das die im Hintergrund wirkenden "Module" dabei sehr Komplex sind, ist für die Anwendung letztlich relativ egal. Die STL ist ein Beispiel für eine solche Bibliothek.

Abgesehen davon ist es natürlich eine hervorragende "Spielerei zu Übungszwecken" die mir eine menge Spaß mach, was auf dich ja ebenfalls zuzutreffen scheint. Das gilt dann eben für all die Teile, die letztlich nicht zum Einsatz kommen. ;-)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: