Aufruf f(const Value<std::string>&)
mit einem Stringliteral würde zwei benutzerdefinierte Konvertierungen erfordern (const char[]
==>std::string
==>Value<std::string>
), um die Funktionsparameter anzupassen, während der Standard nur erlaubt eins.
Ich sehe zwei Möglichkeiten, das zu lösen: Entweder den Konstruktor überlasten oder f()
überlasten.
Angenommen, Sie fragen nach dem ersten, weil letzteres nicht möglich ist, gibt es mehrere Möglichkeiten, den Konstruktor zu überlasten.
Sie können die Tatsache ausnutzen, dass Memberfunktionen einer Klassenvorlage nur kompiliert werden, wenn sie aufgerufen werden, und einen Konstruktor hinzufügen, der nur kompiliert wird, wenn T
einen bestimmten Typ hat. Wenn Benutzer Ihrer Vorlage diese für andere Typen aufrufen, führt dies natürlich zu einem Fehler. Anstatt jedoch ein Problem darin zu sehen, könnte man es Umarmung durch den Konstruktor ein Mitglied Vorlage machen:
template<typename U>
Value(const U& value) : m_value(value) { };
auf diese Weise, was auch immer in T
umgewandelt werden kann (wie auch T
selbst, natürlich) ist erlaubt für U
.
Oder Sie könnten die Klasse für std::string
spezialisieren. Leider müssten Sie dann die ganze Klasse spezialisieren, da es keine selektive Spezialisierung einzelner Mitglieder gibt. In diesem Fall möchten Sie möglicherweise den gesamten Code in eine gemeinsame (möglicherweise private
Basisklasse von Value
, mit der Value
Basisvorlage nur Konstruktoren, die an die Konstruktoren der Basisklasse weiterleiten, und eine Spezialisierung Value<std::string>
, die einen weiteren Konstruktor unter fügt hinzufügen .
ich dachte, es implizit konvertierbar war auch zu machen, aber der Compiler (g ++) beschwert sich darüber (ungültige Initialisierung der Referenz). – rve
und nein, ist die Zeichenfolge kein Platzhalter – rve
@rve: Tut mir leid, das ist ein Brainfart von mir war. Ich konnte nicht erkennen, dass Sie 'f()' mit einer C-Zeichenfolge aufrufen wollten. Ich werde meine Antwort reparieren. – sbi