Kurze Frage zu Template-Funktionen
-
Hi!
Kurze Frage, geht das folgende irgendwie?:
template<typename container> void foo( container<SomeClass> bla ); std::vector<SomeClass> v; foo( v );Ich will also einfach vorgeben, welche Klasse in "container" eingebettet sein soll.
-
Hi,
geht es hier nur im die std-Container ?
-
Würde auf jeden Fall reichen, ja!
-
template<template <typename,typename> class container> void foo( container<SomeClass, std::allocator<SomeClass> > bla );
-
template template parameter sind ziemlicher schrott aktuell - denn container der standard library duerfen unendlich viele template argumente nehmen und damit kommen template template argumente nicht klar. im neuen standard wird das deutlich besser...
was du aber jetzt machen kannst ist mit boost::enable_if und is_same<SomeClass, Container::value_type> zu arbeiten.
Edit:
oder auf iteratoren ranges zu operieren - wenn das moeglich ist...
-
KasF schrieb:
template<template <typename,typename> class container> void foo( container<SomeClass, std::allocator<SomeClass> > bla );Genau das hatte ich gesucht, danke!
Shade Of Mine schrieb:
oder auf iteratoren ranges zu operieren - wenn das moeglich ist...
Wie meinst du das? Im Zusammenhang mit enable_if/is_same oder als generelle Lösung?
-
template <class Allocator, template <typename, typename> class Container> void foo(Container<SomeClass, Allocator> const& c) { }Hilft aber nur für Container mit 2 Template Parametern. Ich habe mal gehört, dass sie allerdings noch interne Default-Template-Parameter haben dürfen, was das ganze natürlich vollkommen unbrauchbar machen würde. Mal davon abgesehen, dass das für Container mit 3 Argumenten auch nicht funktioniert (std::set, map).
Eventuell kannst du mit boost::enable_if arbeiten?
template <class Container> typename boost::enable_if<boost::is_same<typename Container::value_type, SomeClass>, void>::type bar(Container const& c) { }Edit: zu spät...
Gruß
Don06
-
Badestrand schrieb:
KasF schrieb:
template<template <typename,typename> class container> void foo( container<SomeClass, std::allocator<SomeClass> > bla );Genau das hatte ich gesucht, danke!
und es ist nicht portabel wie ich bereits gesagt habe.
Shade Of Mine schrieb:
oder auf iteratoren ranges zu operieren - wenn das moeglich ist...
Wie meinst du das? Im Zusammenhang mit enable_if/is_same oder als generelle Lösung?
als eigene loesung. das was du willst kannst du 1:1 mit enable_if bekommen und bist portabel - template template parameter sind es nicht. enable_if ist hier das richtige.
die frage aber ist, ob du das ganze ueberhaupt brauchst: warum muss es SomeClass sein und darf nichts von SomeClass geerbtes sein? Oder etwas das interface kompatibel ist. Bei vererbung kommt wieder enable_if ins spiel und bei interface kompatibel BOOST_CONCEPT
-
Shade Of Mine schrieb:
und es ist nicht portabel wie ich bereits gesagt habe.
Das hatte ich schon verstanden, trotzdem hatte (Vergangenheit) ich genau das gesucht

die frage aber ist, ob du das ganze ueberhaupt brauchst: warum muss es SomeClass sein und darf nichts von SomeClass geerbtes sein? Oder etwas das interface kompatibel ist. Bei vererbung kommt wieder enable_if ins spiel und bei interface kompatibel BOOST_CONCEPT
Es dreht sich da zum Glück nur um ziemlich simple Typen wo garantiert weder Vererbung noch Interface-kompatible Typen drankommen. Aber danke für die Möglichkeiten, vielleicht brauch ich's später noch mal

-
Würde das im neuen Standard mit Concepts gelöst oder wie?
-
Badestrand schrieb:
Es dreht sich da zum Glück nur um ziemlich simple Typen wo garantiert weder Vererbung noch Interface-kompatible Typen drankommen. Aber danke für die Möglichkeiten, vielleicht brauch ich's später noch mal

Es ist halt eine sinnlose limitierung von generischen code. wenn etwas sich genauso verhaelt wie SomeClass, warum darf ich es dann nicht verwenden wie SomeClass?
Naja, egal. Das wirkliche Problem ist sowieso die template template loesung... Nimm da aber wenigstens Don06s Loesung.
Edit:
Nein im neuen Standard wuerde man das per variadic templates loesen. beim forentreff habe ich mit vinzenz da was gebastelt - eigentlich ich hab gesagt was ich will und vinzenz hats programmiert
- deshalb hab ich jetzt auch gerade null ahnung von der syntax.muss aber in etwa sowas gewesen sein:
template<template<class, class...> class ContainerT, typename... Args> void foo(ContainerT<SomeClass, Args...> const& c) { }Syntax may vary

Das einzige was dabei das problem ist, ist dass SomeClass der erste template parameter sein muss. Was idR zutrifft, aber 100% perfekt ist es nicht. Was danach kommt ist dank variadic templates egal. Auch wenn nichts nach SomeClass kommt.
-
Shade Of Mine schrieb:
Es ist halt eine sinnlose limitierung von generischen code. wenn etwas sich genauso verhaelt wie SomeClass, warum darf ich es dann nicht verwenden wie SomeClass?
Naja, egal. Das wirkliche Problem ist sowieso die template template loesung... Nimm da aber wenigstens Don06s Loesung.
Ich bin mittlerweile doch wieder auf
template<typename container> void foo( container& )umgeschwenkt, die enable_if/is_same Lösung ist prinzipiell zwar schön, optisch aber leider ein Graus. Und du hast mich mit der Generizität überzeugt, es kompiliert bei Interface-Fremdheit ja sowieso nicht
Shade Of Mine schrieb:
template<template<class, class...> class ContainerT, typename... Args> void foo(ContainerT<SomeClass, Args...> const& c) { }Syntax may vary

Sieht schon schicker aus, wenn auch immer noch viel zu tippen

Ich danke euch

-
Badestrand schrieb:
Würde das im neuen Standard mit Concepts gelöst oder wie?
fände ich die schönere lösung.
du definierst einconcept, das aussagt, wie der container aussehen soll - und schwupps*, alle container, die passen, werden akzeptiert; für alle anderen, die die gewünschte funktionalität implementieren, aber deren schnittstelle "falsch" ist, kannst du mit einerconcept_mapdie schnittstelle selbst verbiegen.auto concept MyContainer <typename Cont> { typename size_type; size_type size (Cont const&); }; template <MyContainer c> void foo (c &);bzw. du verwendest die im standard selbst definierten concepts.
#include <container_concepts> template <std::BackInsertionContainer Cont> void foo (Cont&);__________________
* nur beiauto concept