In einem seiner letzten Vorträge empfahl Herb Sutter, die freien begin(container)
end(container)
-Funktionsvorlagen über container.begin()
zu bevorzugen. Ich mag es, weil diese Funktion für alle iterablen Typen bereitgestellt werden kann, die nicht mit Methoden von begin () / end () kommen. Da die meisten meiner Domain-Klassen Schnittstellen haben, die in der Domänensprache sprechen und keine allgemeinen Namen wie begin / end verwenden, kann ich jetzt eine iterierbare Schnittstelle bereitstellen, die kompatibel zu STL-Containern und Range-Base für Loops ist, ohne die Haupt-Klassenschnittstelle zu verpfuschen.
Ich frage mich, was der beste Weg ist, Anfangs- / Endfunktionen für meine eigenen Typen bereitzustellen. Mein erster Gedanke war, es genauso zu machen wie ich mit swap
und schreibe die Funktion in denselben Namensraum, in dem mein Typ lebt.
Ist es in Ordnung, hier in ADL zu arbeiten, oder sollten sie im std-Namespace sein? Ich denke, ein anderer Weg ist eine Spezialisierung im std-Namespace (Überladung in Std. Ist nicht erlaubt, oder?). Was ist der beste Weg, insbesondere in Bezug auf die Suche nach bereichsbasierten Schleifen?
Ich würde ADL seine Arbeit machen lassen. Während Sie im std
-Namespace Spezialisierungen hinzufügen dürfen, gibt es keinen guten Grund dafür, wenn eine einfache freie Funktion in Ihrem Namensraum ausreicht.
Insbesondere für den Bereich für Schleifen gibt der Standard an:
§ 6.5.4 / 1 (Definition von begin-expr und end-expr ):
- andernfalls sind begin-expr und end-expr jeweils
begin(__range)
undend(__range)
, wobei Anfang und Ende mit argumentabhängiger Suche (3.4.2) nachgeschlagen werden. Für die Zwecke dieser Namenssuche ist Namespace std ein zugehöriger Namespace.
Es ist vollkommen in Ordnung und es wird empfohlen, sich auf ADL zu verlassen. Die Funktionen begin
und end
sind Teil der Schnittstelle Ihres Typs (unabhängig davon, ob es sich um freistehende Funktionen handelt oder nicht) und sie sollten sich im selben Namespace befinden wie Ihr Typ.