Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Alle Typen eines tuples in jeweils einen vector verpacken

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 <
000
26.11.2009, 20:08 Uhr
~Prog
Gast


Hi,

ich benutze GCC4.4 mit den Erweiterungen des TR1 und möchte folgendes realisieren:


C++:
template < typename Ein_beliebiges_tuple >
class A{
    std::tuple< std::vector< std::tuple_element< 0, Ein_beliebiges_tuple > >, ... > element;
};



Ich möchte also einer Klasse ein tuple als Templateparameter übergeben und innerhalb der Klasse ein tuple mit vectoren anlegen, welche als Datentyp des jeweils entsprechende Element des übergebenen tuples erhalten.

Wie kann ich dies in C++0x ausdrücken, bzw. ist das überhaupt möglich?


Zur Verdeutlichung noch einmal ein konkretes Beispiel:


C++:
A< int, int, int, float > a;
// a::element sollte jetzt den Datentyp
// std::tuple< std::vector< int >, std::vector< int >, std::vector< int >, std::vector< float > >
// haben




Gruß Prog
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
26.11.2009, 21:01 Uhr
0xdeadbeef
Gott
(Operator)


Dein Beispiel deckt sich grad nicht mit der Deklaration. Wenn ich aber richtig verstehe, was du vorhast, wäre ein std::vector<Ein_beliebiges_tuple> wahrscheinlich die einfachere Lösung.

Ansonsten - bis c++0x mit variadic templates rumkommt, wird das wohl nur von Hand gehen, etwa

C++:
namespace impl {
  template<int i, typename T> struct tvec_aux { };

  template<typename T> struct tvec_aux<0, T> {
    typedef std::tr1::tuple<std::vector<std::tr1::tuple_element<0, T>::type> > type;
  };

  template<typename T> struct tvec_aux<1, T> {
    typedef std::tr1::tuple<std::vector<std::tr1::tuple_element<0, T>::type>,
                            std::vector<std::tr1::tuple_element<1, T>::type> > type;
  };

  template<typename T> struct tvec_aux<2, T> {
    typedef std::tr1::tuple<std::vector<std::tr1::tuple_element<0, T>::type>,
                            std::vector<std::tr1::tuple_element<1, T>::type>,
                            std::vector<std::tr1::tuple_element<2, T>::type> > type;
  };

  // ...
}

template<typename T> struct tuple_vectorizer {
  typedef impl::tvec_aux<std::tr1::tuple_size<T>::value, T>::type type;
};


Womöglich ließe sich da mit Boost.PP was drehen, um das über einen Kamm zu scheren.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
26.11.2009, 21:52 Uhr
0xdeadbeef
Gott
(Operator)


Nachtrag: Beispielsweise so

C++:
#include <boost/preprocessor/repetition.hpp>

#include <tr1/tuple>
#include <vector>

namespace impl {
  template<int I, typename T> struct tvec_aux { };

#define MY_CODE_VEC_PRINT(z, n, data) \
  std::vector<typename std::tr1::tuple_element<n, T>::type>

#define MY_CODE_TVEC_AUX(z, n, unused)         \
  template<typename T> struct tvec_aux<n, T> { \
    typedef std::tr1::tuple<                   \
      BOOST_PP_ENUM(n, MY_CODE_VEC_PRINT, ~)   \
    > type;                                    \
  };

  // Hier ggf. ersten Parameter erhöhen, wenn mehr gewünscht ist
  BOOST_PP_REPEAT(9, MY_CODE_TVEC_AUX, ~)
}

#undef MY_CODE_TVEC_AUX
#undef MY_CODE_VEC_PRINT

template<typename T> struct tuple_vectorizer {
  typedef typename impl::tvec_aux<std::tr1::tuple_size<T>::value, T>::type type;
};

int main() {
  tuple_vectorizer<std::tr1::tuple<int, double> >::type x;

  std::tr1::get<0>(x).push_back(2);
  std::tr1::get<1>(x).push_back(2.0);
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 26.11.2009 um 21:56 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
28.11.2009, 19:23 Uhr
~Prog
Gast


Erst mal vielen Dank! Besonders dein zweites Beispiel ist schon mal super für Compiler die variadic templates nicht beherschen. g++-4.4 kann allerdings bereits variadic templates und mit folgender Klasse kann ich auch problemlos ein "vektorisiertes" tuple aus den Ausgangsdatentypen erzeugen:


C++:
template< typename ... Types > struct vectorizer{
    typedef std::tuple< std::vector< Types > ... > type;
};



Ich möchte vectorizer allerdings gern ein vorhandenes tuple übergeben und diesem die zu "vektorisierenden" Datentypen entnehmen. Auf die von dir gezeigte Weise funktioniert das natürlich, aber ich würde gerne die Möglichkeiten von variadic templates benutzen, um ein tuple aus einer beliebigen Anzahl von Datentypen umzuwandeln.

Gruß Prog
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
28.11.2009, 19:29 Uhr
0xdeadbeef
Gott
(Operator)


Ich hab das jetzt nicht getestet, ich gehe aber davon aus, dass das mit etwa so einer Spezialisierung gehen müsste:

C++:
template<typename... Types> struct vectorizer<std::tr1::tuple<Types> > {
  typedef std::tr1::tuple<std::vector<Types>... > type;
};


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 28.11.2009 um 19:30 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
28.11.2009, 19:45 Uhr
~Prog
Gast


Spezialisierung mit tuple... logisch, danke dir!

Der komplette Code lautet jetzt:


C++:
template< typename ... Types > struct vectorizer{
    typedef std::tuple< std::vector< Types > ... > type;
};

template< typename ... Types > struct vectorizer< std::tuple< Types ... > > {
    typedef std::tuple< std::vector< Types > ... > type;
};



(Die drei Punke bei der template-Expandierung für tuple hattest du noch vergessen. )

Noch'n kleiner allgemeiner Hinweis an andere Leser: Ob man den namespace "tr1" mit angibt ist vom Compiler abhängig. Meiner verhält sich bereits so, als währe das bereits Standard, daher existiert der namespace bei mit nicht.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
28.11.2009, 19:48 Uhr
0xdeadbeef
Gott
(Operator)


Naja, in TR1 steht, dass der Kram im namespace std::tr1 steht. Wenn du allerdings, was ich vermute, den g++ im c++0x-Modus benutzt, dann wird der Kram wohl in std direkt liegen.

So oder so sind variadic templates bisher in noch keinem Standard beschrieben, von daher ist Streit darüber verfrüht - auch wenn dein Code voraussichtlich in Zukunft standardkonform sein wird.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 28.11.2009 um 19:50 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ 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: