Automatisches erkennen des Typs bei boost::make_tuple;
-
Hallo,
folgender Code funktioniert in Visual Studio 2010 nicht:
int dummyFunc() { return 0; } typedef function<int(void)> FUNCTYPE; map<string, boost::tuple<int, string, FUNCTYPE>> funcs; funcs["dummyFunc"] = boost::make_tuple(0, "Dummy-Function", dummyFunc);Es liefert den Fehler:
Fehler 12 error C2664: 'boost::tuples::detail::non_storeable_type<T>::non_storeable_type(const boost::tuples::detail::non_storeable_type<T> &)': Konvertierung des Parameters 1 von 'int (__cdecl &)(void)' in 'const boost::tuples::detail::non_storeable_type<T> &' nicht möglich c:\lib\boost\boost\tuple\detail\tuple_basic.hpp 376 1 test
Dagegen kompiliert folgender Code fehlerfrei:
int dummyFunc() { return 0; } typedef function<int(void)> FUNCTYPE; map<string, boost::tuple<int, string, FUNCTYPE>> funcs; funcs["dummyFunc"] = boost::tuple<int, string, FUNCTYPE>(0, "Dummy-Function", dummyFunc);Warum liefert make_tuple den Fehler und das direkte Anlegen des Tuples klappt?
Gruss Uwe
-
wie siehts aus wenn du das string-literal explizit in einen std::string castest?
-
boost::make_tuple weiß anscheinend nichts mit einem Funktions-Lvalue anzufangen. du kannst ja mal probieren, vor
dummyFuncden Adress-Operator zu verwenden, alsoboost::make_tuple(0, "Dummy-Function", &dummyFunc)So oder so erzeugst du ein temporäres Tuple. Um das loszuwerden könntest Du auch schreiben:
typedef function<int()> func_t; typedef boost::tuple<int,string,func_t> tup_t; map<string,tup_t> funcs; tup_t& tup = funcs["dummyFunc"] boost::get<0>(tup) = 0; boost::get<1>(tup) = "Dummy-Function"; boost::get<2>(tup) = dummyFunc;was sich auch in einer eigenen Funktion verpacken ließe.
Mir ist auch gerade aufgefallen, dass du schon ein C++11 Feature verwendest. Das
>>inmap<string,boost::tuple<int,string,FUNCTYPE>>ist erst ab C++11 gültig. Um auch C++98/03-kompatibel zu bleiben, müsstest du da ein Leerzeichen einfügen, also> >statt>>. Das hat was mit dem Lexer zu tun, der ein>>wegen der MaxMunch-Regel als Shift-Operator interpretieren würde. Ab C++11 gibt es allerdings auch std::tuple, std::make_tuple, Rvalue-Referenzen und praktische Type Traits. Du könntest Deinen Code ja mal mit std::tuple/make_tuple testen. Das klappt dann vielleicht auch schon.
-
kkaw schrieb:
Mir ist auch gerade aufgefallen, dass du schon ein C++11 Feature verwendest. Das
>>inmap<string,boost::tuple<int,string,FUNCTYPE>>ist erst ab C++11 gültig.Alle relevanten Compiler haben das alerdings schon sehr viel früher unterstützt auch wenn es eigentlich kein gültiges C++ war.
-
Mit C++11 kann man da richtig auf die K4cke hauen:
funcs.emplace(std::piecewise_construct, std::forward_as_tuple("dummyFunc"), // <-- Parameter für Key std::forward_as_tuple(0,"Dummy-Func",&dummyFunc) // <-- Parameter für Value );Das müsste das
pair-Objekt direkt in dermaperzeugen. Ist aber ungetestet.
-
TNA schrieb:
Alle relevanten Compiler haben das alerdings schon sehr viel früher unterstützt auch wenn es eigentlich kein gültiges C++ war.
Gegenbeispiel: g++
-
Hallo,
@kkaw
Mir ist auch gerade aufgefallen, dass du schon ein C++11 Feature verwendest. Das
>>inmap<string,boost::tuple<int,string,FUNCTYPE>>ist erst ab C++11 gültig. Um auch C++98/03-kompatibel zu bleiben, müsstest du da ein Leerzeichen einfügen, also> >statt>>.das ist mir klar. Aber Visual Studio 2010 unterstützt teilweise C++11 Features. Ich muss nicht zu C++98/03-kompatibel bleiben.
boost::make_tuple(0, "Dummy-Function", &dummyFunc)
funktioniert!
Gruss Uwe