Partielle Template-Spezialisierung
-
Ok, da hätte ich mir meinen Post ja sparen können. Aber gut, dass das jetzt klar ist.
-
@Badestrand,
Dein Beweis zieht aber nicht. Schau dir mal an, wie du es beweisen willst:
(1) Du nimmst an, std::map hat genau 4 Templateparamter
(2) Du erstellst aufgrund dieser Annahme einWell-formedProgramm.
(3) Du nimmst eine std::map welche mehr als 4 Templateparameter hat.
(4) Dein Programm ist nicht mehrWell-formed.
(5) Daraus schliesst du, dass es 4 Templateparameter sein müssen.Du hast aber nie die Nummer (1) bewiesen! Das ist eine Annahme ohne Beweis. Daher kannst du auch nicht davon ausgehen, dass das Programm
well-formedist. Dadurch funktioniert der Beweis in Nummer (5) nicht mehr.Kann ja sein, dass ich wirklich falsch liege, nur ist der Beweis von Badestrand und Sebastian Pizer falsch. Da sie ihre ursprüngliche Annahme nicht beweisen. Ich möchte ja wirklich verstehen, wieso ich falsch liege. Aber das ist keine gültige Erklärung. Das ist kein Beweis.
Old McDonald schrieb:
Hier die Lösung:
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#94Library Working Group schrieb:
There is no ambiguity; the standard is clear as written. Library implementors are not permitted to add template parameters to standard library classes. This does not fall under the "as if" rule, so it would be permitted only if the standard gave explicit license for implementors to do this. This would require a change in the standard.
Allerdings war man sich wohl auch bei der LWG zunächst nicht sicher, ob der Standard weitere Templateparameter zulässt, wie man an der Bemerkung in eckigen Klammern sieht.
Kann mir einer den Teil ab "This does not fall under ..." erklären? Leuchtet mir nicht so ein, was die da reden. Wieso wird da plötzlich über eine Änderung im Standard geredet? In welchem Zusammenhang stehen diese Sätze?
Denn wenn man in den eckigen Klammern oben liest, dann ist dort die Frage, ob man sowas explizit erlauben möchte, was abgelehnt wurde. Man ist sich allerdings darüber einig, dass es eine Verdeutlichung brauche. Woraus ich persönlich schliesse, dass es nicht so klar im Standard steht.
In dem von Old McDonald zitierten Satz steht aber, dass es klar sei. Und es würde explizit im Standard stehen. Ich frage nochmals: Wo? Ich möchte doch nur wissen, wo? Ich finde es nämlich nicht.Grüssli
-
Dravere schrieb:
(4) Dein Programm ist nicht mehr
Well-formed.Nene, das bleibt well-formed, nur das Verhalten des Programms ändert sich.
Irgendwie hab ich das Gefühl, du verrennst dich da etwas. Ich versuch's nochmal: In 23.3.1 ist die Deklaration von std::map vorgestellt, mit 4 Templateparametern. Und in dem hier viel-zitierten Absatz 8 aus 1.4 steht, dass der Library-Hersteller std::map gerne verändern darf, solange Programme dann noch genauso ablaufen. Genauso ablaufen wie ...? Ja, imo genauso ablaufen wie wenn das Interface aussieht wie im Standard.
So, das scheint mir eine halbwegs schlüssige Argumentation zu sein. Weil du ständig Beweise willst und wir dir nichts liefern können was dir gefällt, drehen wir den Spieß doch mal um: Erklär doch mal, was du wo und wie anders interpretierst oder mit welchen Schlussfolgerungen du nicht einverstanden bist. Sonst macht die Diskussion nämlich keinen Sinn.
-
Badestrand schrieb:
Nene, das bleibt well-formed, nur das Verhalten des Programms ändert sich.
Ja, stimmt, aber nicht so wichtig, kommt dann trotzdem auf dasselbe raus.
Badestrand schrieb:
Ja, imo genauso ablaufen wie wenn das Interface aussieht wie im Standard.
Und nun kommt die Frage der Fragen:
Wo steht im Standard, wie das Interface genau auszusehen hat? Also wo steht, dass es explizit 4 Templateparameter sein müssen?Badestrand schrieb:
Erklär doch mal, was du wo und wie anders interpretierst oder mit welchen Schlussfolgerungen du nicht einverstanden bist. Sonst macht die Diskussion nämlich keinen Sinn.
Das habe ich schon oft getan. Aber gerne nochmals, denn wenn ich von euch die entsprechende Geduld abverlange, dann von mir auch

- Ich aktzeptiere eure Schlussfolgerungen nicht, weil ihr einfach davon ausgeht, dass der präsentierte Code verbindlich ist. Dabei steht nirgends, dass dies der Fall ist. Ihr geht auch einfach davon aus, dass explizit 4 Templateparameter sein müssen, obwohl nirgends steht, dass es nicht mehr sein dürfen.
- Und interpretieren tue ich eigentlich überhaupt nichts. Ich sage nur, dass es nicht im Standard steht, dadurch nicht geregelt ist und deshalb erlaubt ist.Grüssli
-
Gut, ich versuch's mal formaler, vielleicht kann ich mich damit besser ausdrücken

1. Im Standard ist eine Deklaration von std::map enthalten, mit vier Template-Parametern.
2. Es steht nirgendwo, dass std::map mit genau vier Template-Parameter deklariert sein muss.
3. Eine Standard-konforme Implementierung darf "Erweiterungen" zu den Deklarationen im Standard haben.
4. Das Vorhanden-sein dieser "Erweiterungen" darf das Verhalten von Programmen nicht verändern.
5. Das Verhalten von Programmen kann sich ändern, abhängig von zusätzlichen Template-Parametern für std::map.1-2 sind logisch, 3-4 resultieren aus meinem Verständnis von 1.4.8 des Standards, 5 wurde dargelegt. Aus 4 und 5 folgere ich, dass zusätzliche Template-Parameter für std::map keine gültige "Erweiterungen" sind, std::map also deshalb genau vier Template-Parameter besitzen muss.
Ich könnte mir vorstellen, dass unsere Meinungen bezüglich der Erweiterungen divergieren. Ich bin der Meinung, dass die im Standard vorgestellten Deklarationen relativ verpflichtend sind, bis auf mögliche Erweiterungen eben. Und Code, der auf der Deklaration von std::map im Standard beruht, muss sich trotz eventuell vorhandener Erweiterungen identisch verhalten. Imo wäre z.B. eine zusätzliche non-const Version von "empty" eine gültige Erweiterung.
-
Badestrand schrieb:
1. Im Standard ist eine Deklaration von std::map enthalten, mit vier Template-Parametern.
2. Es steht nirgendwo, dass std::map mit genau vier Template-Parameter deklariert sein muss.
3. Eine Standard-konforme Implementierung darf "Erweiterungen" zu den Deklarationen im Standard haben.
4. Das Vorhanden-sein dieser "Erweiterungen" darf das Verhalten von Programmen nicht verändern.
5. Das Verhalten von Programmen kann sich ändern, abhängig von zusätzlichen Template-Parametern für std::map.1-2 sind logisch, 3-4 resultieren aus meinem Verständnis von 1.4.8 des Standards, 5 wurde dargelegt. Aus 4 und 5 folgere ich, dass zusätzliche Template-Parameter für std::map keine gültige "Erweiterungen" sind, std::map also deshalb genau vier Template-Parameter besitzen muss.
Bravo!

Badestrand schrieb:
Imo wäre z.B. eine zusätzliche non-const Version von "empty" eine gültige Erweiterung.
Auf jeden Fall kann das Hinzufügen von Überladungen ein Programm ungültig machen. Beispiel:
void foo(int); // #1 void foo(int*); // #2 (neu hinzugefügt) template<typename T> void sink(T t) {} void bar() { void (*p)(int) = &foo; // OK, Zeiger auf #1 sink(p); // OK, T = void(*)(int) sink(&foo); // Fehler, Mehrdeutigkeit }Ohne #2 kann Typ und Wert von &foo für sink(&foo) eindeutig bestimmt werden.
Gruß,
SP
-
Und um das Bild noch zu vervollständigen, es gibt meiner Meinung nach noch zwei andere wichtige Stellen im Standard, die eine Rolle spielen.
Zunächst zur Bedeutung des C++-Codes:
ISO-C++ 17.5.2.3/6 schrieb:
In some cases the semantic requirements are presented as C++ code. Such code is intended as a specification
of equivalence of a construct to another construct, not necessarily as the way the construct must be
implemented.Wenn man also etwas Gleichwertiges verwendet, das sich so verhält wie der präsentierte C++-Code, so kann man das tun. Was ist nun gleichwertig? Dafür gibt's die "as if"-Regel, die dort in der Erklärung der LWG genannt wird:
ISO-C++ 1.9/1 schrieb:
The semantic descriptions in this International Standard define a parameterized nondeterministic abstract
machine. This International Standard places no requirement on the structure of conforming implementations.
In particular, they need not copy or emulate the structure of the abstract machine. Rather, conforming
implementations are required to emulate (only) the observable behavior of the abstract machine as explained
below.Solange also das, was beobachtet werden kann, sich gleichwertig verhält, ist es implizit erlaubt. Da es aber, sobald Template-Templateparameter verwendet werden, eben nicht mehr gleichwertig ist und sich das beobachtbare Verhalten ändert, sind weitere Templateparameter bei Standardbibliothekklassen verboten.
Weil das aber um ein paar Ecken herum implizit festgelegt wird, war das wohl eine gewisse Zeit lang nicht klar, ob nun weitere Templateparameter erlaubt sind. Ich kann mich auch daran erinnern, dass ich an verschiedenen Stellen gelesen habe, dass weitere Templateparameter möglich sind.
-
Deswegen haben die Standard-Jungs ja auch dazugeschrieben "agreed that clarification is required" (sinngemäss).
(siehe Link von dir)
-
@Badestrand,
Es nützt nichts, wenn du nochmals das gleiche wiederholst, das ändert an meiner Kritik von Punkt 1 nichts. Du gehst davon aus, dass der Code verbindlich ist, ich sage, dass es nicht im Standard steht.
Wenn der Code nicht verbindlich ist, dann ist folgender Programm Code nichtwell-formed:#include <map> template<template<typename, typename, typename, typename> class MapT> struct Foo { }; int main() { Foo<std::map> foo; }Dann gilt auch Punkt 4 nicht mehr, weil es nur das Verhalten von
well-formedProgrammen nicht verändern darf.Um die Argumentation zu rechtfertigen, muss du Punkt 1 beweisen, also dass der Code verbindlich ist.
@Sebastian Pizer,
Was soll das nun mit den Überladungen? Das ist schon klar, aber darum geht es hier ja nicht.@Old McDonald,
Danke! Du bist der erste, welcher in die richtige Richtungen geht
Allerdings so ganz verstanden habe ich es immer noch nicht. Ich wäre da echt noch froh, wenn mir jemand das übersetzen könnte, was die Leute vom Standard als Antwort hingeschrieben haben.Allerdings überzeugen mich deine weiteren Argumente nicht so wirklich. Der Code muss gleichwertig sein, dass ist sehr wage, was damit gemeint ist. Wenn eine std::map einen zusätzlichen Templateparameter mit Defaultparameter hat, ist er meiner Meinung nach gleichwertig.
Später kommt dann diese Definition mit demas-if. Und zwar steht dort, die Implementationen können die Dinge verändern, solange das Resultat den Anforderungen entspricht. Ist die Anforderung anstd::map, dass sie genau 4 Templateparameter hat? Meiner Meinung nach eben nicht.Ihr seid grauenhaft überzeugt davon, dass es ganz klar ist, da bin ich mir einfach nicht so sicher. Ich bin mir dagegen sehr sicher, dass die Standardleute es nicht so gewollt haben. Also grundsätzlich wollten sie nicht, dass jemand zusätzliche Templateparameter in seiner Implementation dazufügt. Allerdings schliesst dies meiner Meinung nach der formulierte Standard nicht ganz aus.
Naja, der nächste Standard steht vor der Tür. In diesem soll es klarer sein und zusätzlich kann man sich dort mit Variadic Templates Abhilfe schaffen

Grüssli
-
Dravere schrieb:
Es nützt nichts, wenn du nochmals das gleiche wiederholst, das ändert an meiner Kritik von Punkt 1 nichts. Du gehst davon aus, dass der Code verbindlich ist, ich sage, dass es nicht im Standard steht.
Schau noch mal nach, meinen Punkt 1 kannst du gar nicht anfechten :p
Ansonsten interpretieren wir anscheinend ein oder zwei Abschnitte aus dem Standard unterschiedlich - kann man nix machen (und wie nun die Lösung auch sein mag, für mich hat's im Code bisher sowieso noch nie eine Rolle gespielt)

-
Okay, nehmen wir das noch einmal vor.
Der C++-Code beschreibt die semantischen Forderungen des Standards an konforme Implementierungen in Bezug auf die Standardbibliothek (17.5.2.3/6 Satz 1).
Der Standard schreibt nun vor, dass die Klassendefinitionen so übernommen werden müssen oder eine gleichwertige Implementierung verwendet werden muss (17.5.2.3/6 Satz 2). Gleichwertig im Sinne des Standards heißt, dass die Implementierung sich so verhalten muss, als ob sie so wie im Standard (also auch im C++-Code) angegeben implementiert wäre; das Verhalten des Programmes nach außen hin darf sich nicht ändern, wenn es im Sinne des Standards well-formed ist (1.9/1 Satz 4).
Ist es nun well-formed, für Standardcontainer angepasste Template-Templateparameter zu verwenden? Ja, denn das Programm hält sich ja an die semantischen Forderungen des Standards (1.3.15), die hier als C++-Code gegeben sind, ansonsten müsste ja eine Regel explizit drin stehen, dass weitere Templateparameter erlaubt sind.
Wenn sich aber das Verhalten eines Programmes, das well-formed ist, durch weitere Templateparameter ändern könnte, dann ist dies von der "as if"-Regel nicht abgedeckt. Folglich ist es nicht erlaubt, weitere Templateparameter hinzuzufügen.Ich denke, so oder so ähnlich wird der Gedankengang beim Kommittee bei der Begründung gewesen sein.
Und nein, im nächsten Standard ist genau dies eben nicht klarer; steht ja schließlich schon über viele Ecken drin. Für die Erklärung hier habe ich schon einen C++0x-Entwurf vom Oktober 2008 genommen.
Allerdings stehen die Aussagen, auf denen meine Argumentation beruht, schon im alten C++-Standard.
-
Zu der Diskussion ist wahrscheinlich der letzte Absatz hiervon interessant, auch wenn leider keine Standard-Stelle angegeben wird.
Felix
Und natürlich hier nochmal von Herb Sutter.
-
Weitere Hinweise:
http://www.progdoc.de/papers/ttp/psi-ttp/psi-ttp.html - (Suche nach "number of template parameters")
http://cboard.cprogramming.com/cplusplus-programming/117112-templating-container-contained-type.html - letzter Post
http://www.c-plusplus.net/forum/viewtopic-var-t-is-220480.html - letzter Post von camper