template aus template
-
Template-Templates funktionieren nur mit
class, nicht mittypename. Die Syntax ist auch ein wenig anders:template <typename X> class Y
-
Danke : >
Ich hab jz folgendes gemacht/machen müssen:
#include <numeric> template<typename T, typename S, template <typename, typename> class TContainer> T GetSum(const TContainer<T, S> &content) { return std::accumulate(content.begin(), content.end(), T()); } #include <iostream> #include <deque> #include <list> #include <vector> int main() { std::vector<int> A(10, 2); std::deque<int> B(10, 2); std::list<int> C(10, 2); std::cout << GetSum(A) << std::endl; std::cout << GetSum(B) << std::endl; std::cout << GetSum(C) << std::endl; }Als ich
Ryuzakis Code-Fragment per copy&paste übernommen hatte, wollte er(MSVC) immer einenallocator<int>ausgeben und hat sich dann (logischerweise) beschwert, dass da kein op<< deklariert ist^^bb
-
unskilled @logged-off schrieb:
Hey...
Geht so etwas in etwa? [...]
Jein.
Was du vermutlich suchst ist folgendes:
template <class T, template <class> class Container > T GetSum(const Container<T> &content) { return std::accumulate(content.begin(), content.end(), T()); }Problem ist allerdings folgendes:
- du musst beim Template-template parameter (also das was ich hier "Container" genannt hab) alle Templateparameter mit angeben. std::vector z.B. hat mindestens noch den Allokator als zweiten Parameter. Damit hieße das dann z.B.template <class T, class A, template <class, class> class Container > T GetSum(const Container<T,A> &content) { return std::accumulate(content.begin(), content.end(), T()); }Damit ist die Behandlung gleich eingeschränkt, denn damit muss jeder Container mit dem du die Funktion benutzen willst, genau zwei Templateparameter haben. Damit wären wir beim nächsten Thema und einer der Unschönheiten im C++-Standard: die Standardcontainer sind nicht verpflichtet, nur genau die vorgeschriebenen Templateparameter zu haben, der Standard überlässt der Implementierung die Möglichkeit, noch zusätzliche Templateparameter zu definieren. Ein std::vector könnte also durchaus als
`template <class T, class Alloc, class Horst, class Wurstbrot, int barfuss>class vector;` definiert sein. Und der passt natürlich wieder nicht auf den template-templateparameter. Ich würde sowas daher eher wie folgt machen:
template <class Container> typename Container::value_type GetSum(Container const& cont);
-
hmm.. das ist ja doof^^
naja - das thema mit "der standard schreibt die anzahl der template-parameter nicht vor" hatten wir schon mal und waren recht gespaltener Meinung dazu.
Naja, dann fällt halt die Überprüfung für den value_type weg, da man mit StaticAssert und typeid ja nicht all zu viel anfangen kann...
ist auch nicht so wichtig.Danke : >
-
unskilled @logged-off schrieb:
naja - das thema mit "der standard schreibt die anzahl der template-parameter nicht vor" hatten wir schon mal und waren recht gespaltener Meinung dazu.
Naja. Er schreibts eben nicht vor. Das ist keine Meinung sondern Tatsache
Wie viele Bibliotheksimplementierungen das dann ausnutzen und tatsächlich weitere Parameter einführen steht auf einem anderen Blatt und war IIRC der strittige Bestandteil der Diskussion.Naja, dann fällt halt die Überprüfung für den value_type weg, da man mit StaticAssert und typeid ja nicht all zu viel anfangen kann...
ist auch nicht so wichtig.Was für eine Überprüfung denn? Kann man sicher trotzdem noch einbauen.
-
pumuckl schrieb:
[...] die Standardcontainer sind nicht verpflichtet, nur genau die vorgeschriebenen Templateparameter zu haben, der Standard überlässt der Implementierung die Möglichkeit, noch zusätzliche Templateparameter zu definieren.
Da gab es ja neulich eine große "Interpretations-Debatte" zu dem Thema. Wenn man sich den Beitrag von Old McDonald anschaut, findet man den Link zu http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#94 in der genau das diskutiert wird.
edit:
Allerdings kann ich dem Text auch nicht ganz entnehmen, wie es gemeint war, was die neue Intention ist und was C++0x daraus macht.
Gruß,
SP
-
Sebastian Pizer schrieb:
Da gab es ja neulich eine große "Interpretations-Debatte" zu dem Thema. Wenn man sich den Beitrag von Old McDonald anschaut, findet man den Link zu http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#94 in der genau das diskutiert wird. Fazit: Eine Standardbibliothek, die zusätzliche default-Template-Parameter für Klassen benutzt ist nicht standardkonform.
Gut zu wissen. Das macht die Situation allerdings für unskilled's GetSum nicht viel besser, zumal std::set auf jeden Fall drei Parameter hat und selbstgestrickte Container nicht unbedingt mehr als einen.
-
Deswegen gibt es auch so Tricks wie "rebind" bei Allokatoren.
btw: Ich habe meinen vorherigen Beitrag editiert.
-
Im Allgemeinen ist es keine gute Idee, sich von der Struktur der Templateparmeter abhängig zu machen, schon aus theoretischen Gründen, weil diese Struktur nichts mit der Funktionalität zu tun hat, die die Funktion vom übergebenen Argument erwartet. Zudem existieren - nicht nur aber auch - aus diesem Grund die Membertypen value_type&co. Die obige Beispielfunktion könnte und sollte also ohne weiteres so geschrieben werden
template <class Container> typename Container::value_type GetSum(const Container& content) { return std::accumulate(content.begin(), content.end(), typename Container::value_type()); }
-
edit...
ok, das hier wollte ich btw:template < typename TChar, typename TTraits = std::char_traits< TChar >, typename TAlloc = std::allocator< typename TTraits::char_type >, template < typename, typename > class TArray = std::deque > class basic_string {};bb