Templates mit Zeigern
-
Ich habe von einem Freund gerade folgende C++ Code-Schnipsel geschickt bekommen.
Nachdem eine vorherige Version ewig nicht ging, funktioniert die hier gepostete:template <typename T> void foo(const T &t) { } void foobar(const int *i) { // leere Typangabe???? foo<>(i); // alternativ auch foo(i) } int main() { int i=6; foobar(&i); return 0; }Leider reicht mein bescheidenes Wissen nicht aus, warum man bei foo nichts angeben kann / darf. Der Compiler holt sich das wohl von selber heißt es.
Kann mir jemand eine Fachtechnische Antwort geben?Was müsste man denn alternativ für den oben aufgeführten Fall eines int* angeben?
-
BasicMan01 schrieb:
Was müsste man denn alternativ für den oben aufgeführten Fall eines int* angeben?
Eigentlich const int*. Aber wieso sollte man das wollen? Der Compiler nimmt dir doch dir Arbeit in dem Fall ab!
-
David_pb schrieb:
Aber wieso sollte man das wollen?
Gute Frage. Würde ja letztendlich bedeuten, dass man bei Templates die Typangabe
GRUNSÄTZLICH? weglassen könnte.
-
David_pb schrieb:
Aber wieso sollte man das wollen? Der Compiler nimmt dir doch dir Arbeit in dem Fall ab!
Z. B., wenn man sowas hier hat:
template <typename T> class foo { public: void bar(const T &t) const { // mach was mit t } }; void foobar(const int *i) { foo<int *> f; f.bar(i); }Wieso meckert er da? Für mich wäre das Ergebnis bei foo<int *> eine Instanz von foo<int *> mit der Methode:
void bar(const int * &t) constFür den Compiler scheinbar nicht, wieso?
-
Nein, nur wenn der Compiler den Typ auflösen kann! Zum Beispiel geht das bei Rückgabetypen (oft) nicht:
template<typename R, typename T> R foo( const T& bla ) { R xyz = ... return xyz; } template<typename T, typename R> R bar( const T& bla ) { R xyz = ...; return xyz; } int x = foo( 42 ); // nein! int x = foo<int>( 42 ); // ja! int x = foo<int, int>( 42 ); // ja! int x = bar( 42 ); // nein! int x = bar<int>( 42 ); // nein! int x = bar<int, int>( 42 );@ Max0r:
Schreib statt dessen:void bar(T const &t) constdann ist die syntaktische Unklarheit eigentlich beseitigt.
-
Nur, wenn die Template-Parameter auch Parameter der Funktion sind, d.h. für den Rückgabetyp gilt dies nicht:
template<class T> string toStr(const T& t) { std::ostringstream str; str << t; return str.str(); } template<class T> T fromStr(const string& s, const T& def = T()) { std::istringstream str(s); T t = def; str >> t; return t; } int main() { string s = toStr(42); // automatische Herleitung (sogar die <> können weggelassen werden) int x = fromStr<int>("42"); // der Rückgabetyp muß angegeben werden };
-
Max0r schrieb:
Wieso meckert er da? Für mich wäre das Ergebnis bei foo<int *> eine Instanz von foo<int *> mit der Methode:
void bar(const int * &t) constFür den Compiler scheinbar nicht, wieso?
Das ist
void bar(int* const& t) constwomit sich die Frage von selbst beantworten sollte.
-
David_pb schrieb:
@ Max0r:
Schreib statt dessen:void bar(T const &t) constdann ist die syntaktische Unklarheit eigentlich beseitigt.
Da kommt der gleiche Compilerfehler wie bei const T &t
-
Logisch kommt der gleiche Fehler. Der Compiler hat im allgemeinen keine Interpretationsprobleme.
-
David_pb schrieb:
Logisch kommt der gleiche Fehler. Der Compiler hat im allgemeinen keine Probleme damit die Syntax richtig zu interpretieren!

Ich wäre sehr dankbar für eine Erklärung, wieso das falsch ist und wie es richtig geschrieben wird.
-
Camper hats ja schon geschrieben, aber nochmal:
void bar(const T &t) constmit T = int* ist:
void bar( int* const& t ) constWenn du aber schreibst:
void bar( T const& t ) constist auf den ersten Blick klar was passiert wenn du T substituierst.
-
David_pb schrieb:
Camper hats ja schon geschrieben, aber nochmal:
void bar(const T &t) constmit T = int* ist:
void bar( int* const& t ) constWenn du aber schreibst:
void bar( T const& t ) constist auf den ersten Blick klar was passiert wenn du T substituierst.
Wenn der Compiler an der Stelle das einsetzt, was ich ans Template übergeb, kommt für mich aber trotzdem raus:
void bar(const T &t) constwird zu:
void bar(const const int * &t) constEin Template is doch ne Schablone, wo an den entsprechenden Stellen meine Template-Parameter eingesetzt werden. Oder net?
-
...
-
also mittlerweile denk ich, dass man lieber
void bar(T const &t) const { } als void bar(const T &t) const { }schreiben sollte, oder?
-
BasicMan01 schrieb:
also mittlerweile denk ich, dass man lieber
void bar(T const &t) const { } als void bar(const T &t) const { }schreiben sollte, oder?
Zumindest entstehen dann nicht diese Verwirrtheiten!
