Funktionszeiger
-
Hallo.
Ich probiere gerade ein paar Spielereien mit Templates und Funktionszeigern aus und habe zwei Probleme.
template<typename T> void f(T) { } void g(); int main() { f(g); }Dieser Code erzeugt einen Linker-Fehler. Meiner Meinung nach ungerechtfertigt. Behalte ich recht?
2. Ich weiss, dass ich die korrekte Überladung einer Funktion mit einem expliziten Cast des Zeigers wählen kann. Beispielsweise:
std::cout << f(static_cast<float(*)(char)>(g));Geht das auch irgendwie ohne dass ich den Rückgabetypen angeben muss? Der gehört ja schliesslich nicht zur Signatur der Funktion.
Gruss.
-
Nein, du hast unrecht.
Du brauchst die Definition der Funktion g, damit deren Adresse als Template Argument übergeben werden kann, selbst wenn du die Funktion nicht aufrufst.
-
Behalte ich recht?
Nein - es gibt einen odr-use von
g. Daher mussgdefiniert sein. Clang ist nicht standardkonform.Zu deinem anderen Problem:
void g(int, long long, float) {} void g(char, long, double) {} template <typename T> struct identity { using type = T; }; template <typename... T> struct deduce_impl { template <typename R, typename... Superfluent> static typename identity<R(*)(T..., Superfluent...)>::type from( R(*f)(T..., Superfluent...) ) { return f; } }; template <typename Call> void bar(Call){} int main() { bar( deduce_impl<char>::from(g) ); }Kannst du in ein Makro packen.
-
Arcoth, mal eine Frage: Wieso identity?
Tuts nicht einfach R(*)(T..., Superfluent...) als return type direkt?
-
Tuts nicht einfach R(*)(T..., Superfluent...) als return type direkt?
Nö, leider nicht.
Mir fällt aber sowieso gerade auf dass das Unsinn ist.
template <typename R, typename... Superfluent> static auto from( R(*f)(T..., Superfluent...) ) -> decltype(f) { return f; }
-
Arcoth schrieb:
Behalte ich recht?
Nein - es gibt einen odr-use von
g. Daher mussgdefiniert sein. Clang ist nicht standardkonform.ODR-Verletzungen bedürfen in der Regel keiner Diagnose...
-
Hallo.
Erstens erscheint mir nun völlig logisch, da hätte ich auch selbst drauf kommen können.

Arcoth schrieb:
Clang ist nicht standardkonform.
Ebenso GCC 4.8.1
Zu zweitens:
Danke Moderator Arcoth, super Lösung. Ich denke, mit einer knackigen kurzen Bezeichnung ist nicht einmal ein Makro nötig.Schönen Tag noch.
-
Arcoth schrieb:
Clang ist nicht standardkonform.
Nochmal selbst getested. clang steigt mit einem Linkerfehler aus. Was soll daran nicht standardkonform sein? Der Compiler kann sich ja gar nicht beschweren, schließlich könnte g ja auch in einer anderen ÜE definiert sein.
-
clang steigt mit einem Linkerfehler aus
Nicht bei mir.
void g(int, long long, float); void g(char, long, double); template <typename T> struct identity { using type = T; }; template <typename... T> struct deduce_impl { template <typename R, typename... Superfluent> static auto from( R(*f)(T..., Superfluent...) ) -> decltype(f) { return f; } }; template <typename Call> void bar(Call){} int main() { bar( deduce_impl<char>::from(g) ); }clang++ -O3 -std=c++1y ...Kompiliert (und linkt) einwandfrei.
Liegt wohl am Optimierungsflag -O3, dasselbe Ergebnis mit GCC (4.9)... hihi, mein Fehler. Entschuldige.

ODR-Verletzungen bedürfen in der Regel keiner Diagnose...
Ja, aber laufen kann das Programm wohl nicht, oder?
-
VS2013 sagt sowohl in Debug als auch in Release
error LNK2001: unresolved external symbol "void __cdecl g(char,long,double)"
Ich schwöre ich habe keine Drogen genommen, aber da steht Arcoth Moderator.

-
nwp3 schrieb:
Ich schwöre ich habe keine Drogen genommen, aber da steht Arcoth Moderator.

http://www.c-plusplus.net/forum/p2406401#2406401
@Arcoth:
Mir ist klar, dass die Syntax dafür beschissen ist, aber gibt es nocht einen anderen Grund? Oder ist das einfach nur für eine schönere Syntax?
-
nwp3 schrieb:
VS2013 sagt sowohl in Debug als auch in Release
error LNK2001: unresolved external symbol "void __cdecl g(char,long,double)"
Ja, mit VS2013 hab ich es auch ursprünglich getestet und den Fehler erhalten.
nwp3 schrieb:
Ich schwöre ich habe keine Drogen genommen, aber da steht Arcoth Moderator.

Bei mir auch, und?

Vielleicht ist es ein wenig falsch 'rübergekommen. Das war nicht ironisch gemeint oder so sondern soll in leichter Form zur Erkürung zum Moderator gratulieren.