5 Stimmen

Welche Gründe sprechen dagegen, das Überladen des C++-Konvertierungsoperators mit Nicht-Mitgliedsfunktionen zuzulassen?

C++0x hat explizite Konvertierungsoperatoren hinzugefügt, aber sie müssen immer als Mitglieder der Klasse Source definiert werden. Dasselbe gilt für den Zuweisungsoperator, er muss in der Zielklasse definiert werden.

Wenn die Quell- und Zielklassen der benötigten Konvertierung unabhängig voneinander sind, kann weder die Quelle einen Konvertierungsoperator definieren, noch kann das Ziel einen Konstruktor aus einer Quelle definieren.

Normalerweise erhalten wir sie durch die Definition einer bestimmten Funktion wie

Target ConvertToTarget(Source& v);

Wenn C++0x die Überladung des Konvertierungsoperators durch Nicht-Member-Funktionen erlauben würde, könnten wir zum Beispiel die Konvertierung implizit oder explizit zwischen nicht verwandten Typen definieren.

template < typename To, typename From >
operator To(const From& val);

Wir könnten zum Beispiel die Umwandlung von chrono::time_point in posix_time::ptime wie folgt spezialisieren

template < class Clock, class Duration>
operator boost::posix_time::ptime(
const boost::chrono::time_point<Clock, Duration>& from)
{
  using namespace boost;
  typedef chrono::time_point<Clock, Duration> time_point_t;
  typedef chrono::nanoseconds duration_t;
  typedef duration_t::rep rep_t;
  rep_t d = chrono::duration_cast<duration_t>(
  from.time_since_epoch()).count();
  rep_t sec = d/1000000000;
  rep_t nsec = d%1000000000;
  return  posix_time::from_time_t(0)+
    posix_time::seconds(static_cast<long>(sec))+
    posix_time::nanoseconds(nsec);
}

Und verwenden Sie die Konvertierung wie jede andere Konvertierung.

Eine ausführlichere Beschreibung des Problems finden Sie unter ici oder auf meinem Boost.Conversion Bibliothek.

Die Frage ist also: Was ist der Grund dafür, das Überladen des C++-Umwandlungsoperators mit Nicht-Mitgliederfunktionen nicht zuzulassen?

5voto

CB Bailey Punkte 693084

Um herauszufinden, ob man zwischen zwei Klassen konvertieren kann, muss man bei den derzeitigen Regeln nur an zwei Stellen nachsehen: in der Quell- und der Zieldefinition. Wenn man Konvertierungen als Nicht-Mitglieder-Funktionen definieren könnte, könnte die Konvertierungsfunktion überall sein, was die Suche nach der Ursache von unerwünschten oder mehrdeutigen Konvertierungen sehr viel schwieriger machen könnte (zusätzlich dazu, dass der Compiler mehr Arbeit hat, um mögliche Konvertierungen in allen Fällen zu finden, in denen eine Konvertierung notwendig oder möglich ist, z. B. bei Operatorüberladung).

Ich glaube nicht, dass die von Ihnen vorgeschlagene Vorlage sehr praktisch ist. Obwohl man sie explizit für Konvertierungen spezialisieren könnte, für die es einen geeigneten Sonderfall gibt, würde sie immer noch alle anderen Konvertierungen abfangen, was zu Mehrdeutigkeiten mit bereits vorhandenen Konvertierungen führen würde.

Dies sind vielleicht zwei Faktoren, die gegen eine solche Umwandlung sprechen.

1voto

Bill Punkte 13799

Wenn es keinen direkten Zusammenhang gibt zwischen Source et Destination dann möchte ich Umwandlungen zwischen ihnen explizit kennzeichnen, wie bei einer Source sourceFromDestination(const Destination&) Funktion, um nicht von zufälligen impliziten Konvertierungen überrascht zu werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X