Bin mal wieder blind... (STL) STL-Bug?
-
Komischerweise geht ja das auch nicht (was zwar weniger performant, mir aber lieber wäre):
command_table[L"help"] = print_help;error C3853: '=': re-initializing a reference or assignment through a reference-to-function is illegal
-
Zeig mal ein komplettes Beispiel. Habs mal eben mit MSVC++ 2008 getestet und der bringt bei höchster Warnstufe keine Warning.
-
(Theoretisch) Kompilierbares Minimalbeispiel:
#include <string> #include <iostream> #include <map> void print_help() { std::wcout << L"Hilfe:\tshutdown\t- Fährt den Server herunter\n" << L"\thelp\t- Zeigt das Hilfemenü\n"; } int main() { std::map<std::wstring, void (*)()> command_table; command_table.insert(std::make_pair(L"help", print_help)); }Sind die 3 Fehler. Ich benutze Visual C++ Express 2010.
Schreibe ich void () bekomme ich noch die Warnung, schreibe ich nur void (*)() bekomme ich nur die 3 Fehler.
-
Okay, bei mir geht es in Visual Studio 2008 Professional anstandslos zu kompilieren. Das ist ein Bug in der MS-STL-Implementierung von VS 2010 denke ich mal. Aber darauf muss doch schon mal einer gestoßen sein?! Bugs sind doch echt nur für Beta!

Hier sind ja auch STL-Probleme aufgeführt:
Die haben irgendwas mit den neuen Rvalue-Referenzen und Perfect Forwarding zerschossen, denke ich. Och menno...

-
So, ich habe einen Wrapper gebastelt. Nur ist der weder schön, noch kommt er mit Funktionen wie void (void) klar.
#include <string> #include <iostream> #include <map> void print_help (int) { std::wcout << L"Hilfe:\tshutdown\t- Fährt den Server herunter\n" << L"\thelp\t- Zeigt das Hilfemenü\n"; } template <typename T, typename R> struct fun_ptr : std::unary_function<T, R> { fun_ptr(R (*param)(T)) : ptr(param) { }; R operator()(T p) { return ptr(p); } private: R (*ptr)(T); }; int main() { typedef fun_ptr<int, void> fun; std::map<std::wstring, fun> p; fun f(print_help); p.insert(std::make_pair(L"help", f)); }Geht das kürzer? Und vor allem: dass ich Funktionen benutzen kann, die keinen Parameter nehmen?
-
So funktioniert es auch mit VS2010.
#include <string> #include <iostream> #include <map> void print_help() { std::wcout << L"Hilfe:\tshutdown\t- Fährt den Server herunter\n" << L"\thelp\t- Zeigt das Hilfemenü\n"; } int main() { std::map<std::wstring, void (*)()> command_table; command_table.insert(std::make_pair(L"help", &print_help)); return 0; }Früher funktionierte dies nicht:
void (*f)() = &print_help; (*f)();Anscheiend haben Sie doch in C++0x sinnvolles hinzugefügt.
-
Ist natürlich schöner, aber dennoch: das kann doch nicht standardkonform sein? Ob man nun vor der Funktion '&' schreibt oder nicht ist bei Nicht-Elementfunktion doch AFAIK egal?! Naja, danke für den Hinweis, jetzt kann ich weitermachen!

Edit: Dein letztes Beispiel ist doch für C++98 vollkommen konform? Es funktionier auf jeden Fall in VS 2008, auch wenn man doch lieber das schreiben sollte:
void (*f)() = print_help; f();
-
Und das funktioniert leider auch nicht:
command_table[L"help"] = &print_help;
-
*hust* doch tut es
Zeig mal Code oder/und Fehlermeldung 
-
Probiers doch mal so:
typedef void(*funcPtr)(); std::map<std::wstring, funcPtr> command_table; command_table.insert(std::make_pair(L"help", &print_help)); // & ist notwendig command_table[L"help"]();Getestet in VS 2010.
-
Nochmal eine kurze Nachfrage...
Wofür steht das L vor dem "Test" String?
Weiß nämlich nicht, wie ich mir eine Antwort ergooglen könnte ^^
-
Newbie19 schrieb:
Nochmal eine kurze Nachfrage...
Wofür steht das L vor dem "Test" String?
Weiß nämlich nicht, wie ich mir eine Antwort ergooglen könnte ^^Eine Zeichenkette mit dem Präfix L, wie etwa
L"help"ist eine Zeichenkette von WideChars. Ihr Typ ist
const wchar_t[]
-
Ad aCTa schrieb:
I[...]Ob man nun vor der Funktion '&' schreibt oder nicht ist bei Nicht-Elementfunktion doch AFAIK egal[...]
Nein, ist es nicht. Wie bei allen Dingen für die man eine Referenz haben will, muss man auch bei Funktionen den Referenzoperator davor schreiben.
-
Es ist ein Adressoperator, den man auch weglassen kann.
Wie wäre es denn mit
functionObjekten?
-
> Nein, ist es nicht. Wie bei allen Dingen für die man eine Referenz haben will, muss man auch bei Funktionen den Referenzoperator davor schreiben.
Ich will ja keine Referenz, sondern einen Zeiger. Und Funktionen bilden da eigentlich eine Ausnahme, wo man den Adress-Operator nicht angeben muss. In meinen anderen VS 2008-Implementierungen habe ich es auch so gemacht, und ich glaube mich zu erinnern, dass in "Die C++ Programmiersprache" ein ähnliches Beispiel zu finden war. Oder ich habe da noch eine gewaltige Wissenslücke gehabt.

Auf jeden Fall danke für die Hilfe!
-
Ad aCTa schrieb:
Oder ich habe da noch eine gewaltige Wissenslücke gehabt.
Nein, so wie Arrayausdrücke beim kleinsten Anzeichen von Gefahr in einen Zeiger umgewandelt werden, werden (lvalue-)Funktionsausdrücke ebenso implizit in Funktionszeiger umgewandelt wenn nötig (4.3). Zusätzlich wird - was hier bei make_pair eine Rolle spielt - eine Funktionsargument als Funktionszeiger deduziert (14.8.2.1/2 2. Alt).