Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   

Die mobilen Seiten von c++.de:
http://m.c-plusplus.de
Infos hier [BETA]

  
c++.de :: C++ (auch C++0x und C++11) ::  TMP: Permutationen von Template-Parametern generieren  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
Dobi
Mitglied

Benutzerprofil
Anmeldungsdatum: 24.03.2006
Beiträge: 672
Beitrag Dobi Mitglied 13:30:51 25.05.2012   Titel:   TMP: Permutationen von Template-Parametern generieren            Zitieren

Hallo zusammen,

ich überlege gerade, ob man meine Factory-Funktion MakeBar mittels TMP oder sonstwie eleganter hinbekommen könnte, habe aber noch überhaupt keinen Ansatz. Etwas mit Andreischen typelists vielleicht?

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <memory>
 
struct Foo1 {};
struct Foo2 {};
struct Foo3 {};
 
struct BarBase {};
 
template<typename T1, typename T2>
struct Bar : public BarBase {};
 
typedef std::unique_ptr<BarBase> BarPtr;
 
BarPtr MakeBar( int id1, int id2 ) {
    if ( id1 == 1 && id2 == 1 )
        return BarPtr( new( Bar<Foo1, Foo1> ) );
    else if ( id1 == 1 && id2 == 2 )
        return BarPtr( new( Bar<Foo1, Foo2> ) );
    else if ( id1 == 1 && id2 == 3 )
        return BarPtr( new( Bar<Foo1, Foo3> ) );
    else if ( id1 == 2 && id2 == 1 )
        return BarPtr( new( Bar<Foo2, Foo1> ) );
    else if ( id1 == 2 && id2 == 2 )
        return BarPtr( new( Bar<Foo2, Foo2> ) );
    else if ( id1 == 2 && id2 == 3 )
        return BarPtr( new( Bar<Foo2, Foo3> ) );
    else if ( id1 == 3 && id2 == 1 )
        return BarPtr( new( Bar<Foo3, Foo1> ) );
    else if ( id1 == 3 && id2 == 2 )
        return BarPtr( new( Bar<Foo3, Foo2> ) );
    else if ( id1 == 3 && id2 == 3 )
        return BarPtr( new( Bar<Foo3, Foo3> ) );
    return BarPtr();
}
 
int main() {
    int userInput1( 2 );
    int userInput2( 3 );
    BarPtr ptr( MakeBar( userInput1, userInput2 ) );
}


Irgendwelche Ideen, wie man das viele Instanziieren des Klassentemplates nicht mehr manuell machen muss?

Gruß
Dobi
camper
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.08.2004
Beiträge: 5798
Beitrag camper Mitglied 14:00:14 25.05.2012   Titel:              Zitieren

Das geht, ich habe allerdings gerade keinen Compiler zur Hand, um eine fertige Lösung zu erstellen (außerdem ist das eine der Aufgaben für PI :p)
Kurz skizziert könnte das ungefähr so aussehen (wobei mir diese Lösung nihct besonders gut gefällt), da ohne Compiler komplett ungetest und wahrscheinlich auch mit einigen Syntaxfehlern:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
template <typename... T>
struct typelist : std::identity<typelist<T...>> {};
 
template <typename... L>
struct concat_typelists : std::identity<concat_typelists<typename L::type>> {};
 
template <typename... T, typename... U, typename... L>
struct concat_typelists<typelist<T...>, typelist<U...>, L...> : concat_typelists<typelist<T..., U...>, L...> {};
 
template <std::size_t... N, typename L>
struct repeat_list;
 
template <std::size_t... N, typename... T>
struct repeat_list<N, typelist<T...>> : concat_typelists<typelist<T...>, repeat_list<N-1, T...>> {};
 
template <typename... T>
struct repeat_list<0, typelist<T...>> : typelist<> {};
 
template <std::size_t... N, typename L>
struct repeat_types;
 
template <std::size_t... N, typename... T>
struct repeat_types<N, typelist<T...>> : concat_typelists<repeat_list<N, T>...> {};
 
template <typename T, typename U>
void foo();
 
template <typename... T, typename... U>
void dispatch_helper(std::size_t i, typelist<T...>, typelist<U...>)
{
    static const void (*foos[])() = { foo<T, U>... };
    return foos[i]();
}
 
template <typename... T>
void dispatch(std::size_t i, std::size_t j)
{
    using types = typelist<T...>;
    using types_repeated = repeat_types<sizeof...(T), types>;
    using list_repeated = repeat_list<sizeof...(T), types>;
    dispatch_helper(i*sizeof...(T)+j, types_repeated(), list_repeated());
};
pyhax
Mitglied

Benutzerprofil
Anmeldungsdatum: 22.11.2011
Beiträge: 692
Beitrag pyhax Mitglied 12:04:20 26.05.2012   Titel:              Zitieren

C++:
template <typename... T>
struct typelist : std::identity<typelist<T...>> {};


Wie funktioniert das ? Warum erbt camper hier von std::identity ??

_________________
Ich kann (teilweise): C++, Python, Java(ist lange her), PHP, D (Anfänger)
314159265358979__
Unregistrierter




Beitrag 314159265358979__ Unregistrierter 12:13:30 26.05.2012   Titel:              Zitieren

Das ist ein TMP-Abkürzungs-Trick. std::identity ist äquivalent zu:
C++:
template <typename T>
struct identity
{
    typedef T type;
};


Da viele TMP-Algorithmen ihr Ergebnis durch ein typedef type herausgeben, lässt sich ein Algorithmus xyz
C++:
template <typename Foo>
struct xyz
{
    typedef Foo type;
};

kürzer schreiben als
C++:
template <typename Foo>
struct xyz
    : identity<Foo>
{};


camper lässt nun seine typelist selbst von std::identity erben. Wenn er nun als Ergebnis eine Leere Typliste haben möchte, kann er deshalb nochmal abkürzen und statt
C++:
: identity<typelist<>>

direkt
C++:
: typelist<>

schreiben. Sein repeat_list macht davon Gebrauch.
314159265358979__
Unregistrierter




Beitrag 314159265358979__ Unregistrierter 12:16:07 26.05.2012   Titel:              Zitieren

Pseudo-Edit: Das "Leere" aus dem letzten Satz streichen. Geht natürlich mit allen Typlisten.
pyhax
Mitglied

Benutzerprofil
Anmeldungsdatum: 22.11.2011
Beiträge: 692
Beitrag pyhax Mitglied 12:28:26 26.05.2012   Titel:              Zitieren

Ok, danke. Ich wusste vorher noch gar nicht, das man mehr als ein Variadic Template Argument haben kann. :live:

_________________
Ich kann (teilweise): C++, Python, Java(ist lange her), PHP, D (Anfänger)
314159265358979__
Unregistrierter




Beitrag 314159265358979__ Unregistrierter 12:31:46 26.05.2012   Titel:              Zitieren

Das geht auch nur bei Klassentemplate-Spezialisierungen und Funktionstemplates wo die Parameter deduziert werden können.
pyhax
Mitglied

Benutzerprofil
Anmeldungsdatum: 22.11.2011
Beiträge: 692
Beitrag pyhax Mitglied 12:34:37 26.05.2012   Titel:              Zitieren

314159265358979__ schrieb:
Das geht auch nur bei Klassentemplate-Spezialisierungen und Funktionstemplates wo die Parameter deduziert werden können.

Ja, das habe ich mir auch schon gedacht. Sonst wäre das ja nicht mehr eindeutig.

_________________
Ich kann (teilweise): C++, Python, Java(ist lange her), PHP, D (Anfänger)
Dobi
Mitglied

Benutzerprofil
Anmeldungsdatum: 24.03.2006
Beiträge: 672
Beitrag Dobi Mitglied 22:12:31 26.05.2012   Titel:              Zitieren

Wow, super, vielen Dank. Jetzt mach ich mich mal ans Verstehen. ;)
Unregistrierter





Beitrag Unregistrierter 23:00:04 26.05.2012   Titel:              Zitieren

314159265358979__ schrieb:
Wenn er nun als Ergebnis eine Leere Typliste haben möchte, kann er deshalb nochmal abkürzen und statt
C++:
: identity<typelist<>>

direkt
C++:
: typelist<>

schreiben. Sein repeat_list macht davon Gebrauch.

Wenn ich das jetzt richtig verstehe, heißt das, dass eine Klasse von sich selbst ableiten kann? o.O
c++.de :: C++ (auch C++0x und C++11) ::  TMP: Permutationen von Template-Parametern generieren  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.