Ich verstehe, dass bei der generischen Programmierung Algorithmen von Containern entkoppelt sind. Es würde also keinen Sinn machen, einen generischen Algorithmus als Instanzmethode zu implementieren (derselbe Algorithmus sollte an mehreren konkreten Klassen arbeiten; wir wollen nicht, dass sie alle von einem ABC erben, da dies die Anzahl der Klassen exponentiell erhöhen würde).Warum ist Boost Graph Library `source()` eine globale Funktion?
Aber im Fall von source()
Funktion in der Boost Graph Library, verstehe ich nicht, warum es eine globale Funktion und keine Instanzmethode einer Graphenklasse ist.
Soweit ich durch das Lesen der BGL source code sagen konnte, muss source(e, g)
die Implementierungsdetails der Graph und Randobjekte an sie übergeben kennen; es ist nicht genug, nur ihre Schnittstellen zu kennen.
Also source()
ist kein generischer Algorithmus. Mit anderen Worten, es muss die konkrete Klasse der Graphinstanz kennen. Warum also nicht in dieselbe Klasse wie eine Instanzmethode? Wäre es nicht viel sauberer/weniger verwirrend als eine globale Funktion zu erstellen, die an jede Klasse angepasst werden muss?
UPDATE
Der entsprechende Quellcode:
// dwa 09/25/00 - needed to be more explicit so reverse_graph would work.
template <class Directed, class Vertex,
class OutEdgeListS,
class VertexListS,
class DirectedS,
class VertexProperty,
class EdgeProperty,
class GraphProperty, class EdgeListS>
inline Vertex
source(const detail::edge_base<Directed,Vertex>& e,
const adjacency_list<OutEdgeListS, VertexListS, DirectedS,
VertexProperty, EdgeProperty, GraphProperty, EdgeListS>&)
{
return e.m_source;
}
namespace boost {
namespace detail {
template <typename Directed, typename Vertex>
struct edge_base
{
inline edge_base() {}
inline edge_base(Vertex s, Vertex d)
: m_source(s), m_target(d) { }
Vertex m_source;
Vertex m_target;
};
}
}
Kein Grund Quelle (a, b) kann nicht basierend auf den Typen seiner Parameter spezialisiert werden. Nicht alles muss eine Mitgliedsfunktion sein. Einige freie Funktionen können als Teil der Schnittstelle einer Klasse angesehen werden. Zusätzlich kann es nützlich sein, source() als Shim zu verwenden. Ohne den Code zu lesen und zu verstehen (was nicht innerhalb von 2 Klicks auf Ihre Links möglich ist), konnte ich Ihnen das nicht wirklich sagen, da ich die Graphenbibliothek nicht verwende, aber sie könnten Dinge sein, die zu berücksichtigen sind. Alternativ senden Sie die BGL-Entwickler direkt und fragen nach ihrer Designentscheidung. Ich nehme an es gibt einen guten Grund dafür – Pete
Gibt es einen Grund, warum es dich stört? – Pete
http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197 –