wchar_t* template Spezialisierung
-
Hey! Was soll das Gekicher und das q.e.d.?

Das Problem hier hat mit den vorgetragenen Argumenten von Überladung vs. Spezialisierung nur wenig zu tun.
Und außerdem funktioniert Überladung hier auch nur mit Änderung der Semantik
Denn mit
void doSomething(wchar_t const* value) { }ist value keine Referenz auf das übergebene Objekt wie es das Template vorschreibt, was man mit einfacher Ausgabe der Adresse beweisen kann.
Will man mit derselben Semantik, also einer Referenz arbeiten funktioniert auch die Überladung mit der normalen Funktion nicht mehr. Ist halt so bei Arrays.
-
Das Problem hier hat mit den vorgetragenen Argumenten von Überladung vs. Spezialisierung nur wenig zu tun.
Falsch. Es hat alles damit zu tun. Mal davon abgesehen dass der OP ein const vergessen hat.
Und außerdem funktioniert Überladung hier auch nur mit Änderung der Semantik
Falsch.
// primary template template<typename T> void doSomething(T const& value) { } // template-overload mit gleicher semantik template <size_t N> void doSomething(wchar_t const (&value)[N]) { }Will man mit derselben Semantik, also einer Referenz arbeiten funktioniert auch die Überladung mit der normalen Funktion nicht mehr. Ist halt so bei Arrays.
Richtig. Dafür mit einem Template-Overload. Was genau das Thema des anderen Artikels ist

-
@hustbear
Ich weiß nicht, ob du mich absichtlich falsch verstehst, oder ob wir uns mißverstanden haben. Ich beziehe mich die ganze Zeit auf die Überladung mit einer NORMALEN Funktion. Das war das Thema des anderen Threads und auch der Vorschlag von Dravere, siehe oben und hier:
Emberlei schrieb:
Hallo, was ist besser?
template<typename T> void doSomething(T a) {}; //Variante 1 void doSomething(int a) {}; //Einfache Überladung //Variante 2 template<> void doSomething(int a){}; //Template-SpezialisierungWelche Vorteile/Nachteile bieten die beiden Varianten? Was ist die übliche Variante? Was benutzt ihr?
Über die Überladung mit einem Template habe ich nicht gesprochen, daher kann ich das erste "FALSCH" und auch das zweite nicht akzeptieren. Bitte das nächste Mal genauer lesen.
Es ist recht ermüdend hinterherzulaufen, wenn jemand einem das Wort im Mund umdreht.
-
@Mitleid:
Und ich rede von Spezialisierung vs. Überladung, egal ob Überladung mit normalen Funktionen oder Funktions-Templates. Macht für mich keinen Unterschied.p.S.: die "sicherste" Variante ist IMO die Delegation an ein Klassen-Template.
p.p.S.: vielleicht magst du mir ja erklären, wieso für dich die Unterscheidung zwischen Überladung mit einer normalen Funktion vs. mit einem Funktions-Template wichtig/relevant ist?
-
Uh, wtf xD Hier bricht ja wie im anderen Thread gleich wieder ein halber Krieg aus xD
Gugi schrieb:
Rumprobieren (z.B. const wchar_t* const &, oder const wchar_t[]) und google haben nichts gebracht...
Ein paar der Versionen, die ich probiert habe:
template <class T> void DoSomething(const T& Value); // Allgemein void DoSomething(const wchar_t* const Value); // Kompiliert void DoSomething(wchar_t const * Value); // Kompiliert template <> void DoSomething<const wchar_t*>(const wchar_t* const & Value); // Kompiliert template <> void DoSomething<const wchar_t* const>(const wchar_t* const & Value); // Kompiliert template <> void DoSomething<const wchar_t&>(const wchar_t& Value); // Fehler DoSomething(L"Test");Wenn es kompiliert, funktioniert es nicht. Es wird die allgemeine template Version aufgerufen (oder zumindest nicht die spezialisierte/die überladene Version).
In eine extra Klasse würde ich es nur ungern packen... Es muss doch eine Möglichkeit geben, dass es auch so möglich ist.
-
Gugi schrieb:
Es muss doch eine Möglichkeit geben, dass es auch so möglich ist.
hustbear hat es bereits ansatzweise hingeschrieben, sie oben unter "// template-overload mit gleicher semantik"
Dein Problem ist die Referenz. Wenn du ein Array daran binden willst müssen auch die Array-Grenzen übereinstimmen. Dafür brauchst du dieses zweite Template. Darin muss ja mehr oder weniger nicht viel stehen, außer ein expliziter Auruf der Spezialisierung.
Also ein Möglichkeit:
template <class T> void DoSomething(const T& Value); // Dann die Spezialisierungen. Unterschied const <-> nicht const beachten template<> void DoSomething<const wchar_t*> ... template<> void DoSomething<wchar_t*>... // und dann das zweite Template template <size_t N> void doSomething(wchar_t const (&value)[N]) { doSomething<const wchar_t*>(value); }P.S.: Wenn du mit const usw. durcheinander kommst, dann hilft manchmal ein typedef an der einen oder anderen Stelle.
P.S.2: Ist nur ein Tipp für einen Ansatz, hab jetzt selbst nicht überprüft ob alles übereinstimmt sondern nur zusammenkopiert.:)
-
Gugi schrieb:
Wenn es kompiliert, funktioniert es nicht.
Tut mir leid, aber das glaub ich dir nicht. Dieser Fall funktioniert ganz sicher:
#include <iostream> template<typename T> void doSomething(T const& value) { std::cout << "T const&" << std::endl; } void doSomething(wchar_t const* value) { std::cout << "wchar_t const*" << std::endl; } int main() { doSomething(L"Hello"); return 0; }Da wird ein "wchar_t const*" auf der Konsole ausgegeben. Wenn nicht, dann möchte ich gerne Wissen, welchen Kompiler du benutzt.
Grüssli
-
@Mitleid: könntest du den Spezialisierungs-Unsinn sein lassen, und lieber meine Frage beantworten?

-
hustbaer schrieb:
@Mitleid: könntest du den Spezialisierungs-Unsinn sein lassen, und lieber meine Frage beantworten?

Wenn du Beiträge editierst und Fragen hinzufügst bekommt das nicht jeder mit.;) Ich zumindest nicht.
Ich mache die Unterscheidung nur, weil das der Inhalt von Emberleis Frage war. Nachdem du recht einsilbig geblieben bist und nur mit einem "Ich würde grundsätzlich einen Overload vorziehen." geantwortet hast, hast du in meinen Augen gesagt du würdest grundsätzlich mit einer normalen Funktion überladen. Das hätte ich halt gerne nochmal begründet gehabt.
Wenn du (hoffentlich damals schon) auch die Überladung mit Templates gemeint hast (was nicht der Inhalt von Emberleis Frage war), dann haben wir ja kein Differenzen. Dann brauchst du nur noch deine Variante für Gugi ohne die (angeblich unsinnigen) Spezialisierungen hier hineinschreiben und alle sind glücklich.
-
@Mitleid: Die ganzen const Varianten waren nur Beispiele meiner Versuche.
Und: Ich bin ein totaler Volldepp...
Ich hab nämlich, wie mir gerade bewusst geworden ist, noch ein template-overload (oder wie man das nennt):template<class T> void DoSomething(int AParamter, const T& Value); void DoSomething(int AParameter, const wchar_t* Value); template<class T> void DoSomething(const T& Value) { DoSomething<T>(0, Value); }Im Testcode hab ich DoSomething so aufgerufen:
DoSomething(L"Test");Da isses klar, dass er die allgemeine Version aufruft. So gehts:
template<class T> void DoSomething(const T& Value) { DoSomething(0, Value); }Also, es funktioniert jetzt. Danke an alle
Wär mir sonst nie aufgefallen.