Implizite Konvertierung zu Const -.-
-
Hallo da,
ich hatte den Plan, durch zwei unterschiedliche Member die Mehrdeutigkeit zwischen const und non-const-Versionen von Methoden zu unterscheiden:
template<typename Ret, typename C, typename... Args, typename... Injectors> class_& def_nonconst(char const* name, Ret(C::*fn)(Args...), meta::type_list<Injectors...> policies = no_injectors()) { return def(name, fn, policies); } template<typename Ret, typename C, typename... Args, typename... Injectors> class_& def_const(char const* name, Ret(C::*fn)(Args...) const, meta::type_list<Injectors...> policies = no_injectors()) { return def(name, fn, policies); }Leider scheitert die const-Variante daran, dass Methodenzeiger offenbar implizit in in const-Methodenzeiger konvertiert werden können. Ich bin fast überzeugt, dass es keine Möglichkeit gibt, da etwas zu machen, aber vielleicht fällt euch doch noch etwas total gutes dazu ein?
Viele Grüße,
decimad
-
Ich habe erst mal den ersten und dritten Parameter entfernt, da diese nicht essenziell waren:
template<typename Ret, typename C, typename... Args> class_& def_nonconst( Ret(C::*fn)(Args...) ) { return def(name, fn, policies); } template<typename Ret, typename C, typename... Args> class_& def_const( Ret(C::*fn)(Args...) const ) { return def(fn); }
-
Meintest du das hier:
Ret(C::* const fn)(Args...)?
-
Ja, das meinte ich! Das rettet mich vor leidvollen static_casts! Von welchem Typ war denn meine versuchte Zeiger-Zu-Const-Methode wirklich? Oo
-
Und vor allem, warum hat dasselbe bei static_cast funktioniert? Oo
-
Also ich meine:
static_cast<int(Klasse::*)() const>(&Klasse::Methode);löst die Mehrdeutigkeit auf... Ist das normal, dass ohne einen "Namen" für die Sache das const dahinter stehen darf?
-
Hrmmm,
static_cast<int(Klasse::* const)()>(&Klasse::Methode);kompiliert nicht... Ich wundere mich gerade irgendwie...
-
Hallo nochmal, ich bin irgendwie gerade verwirrt, aber kann an keinen 2013RC-Compiler...
Folgender Code kompiliert mit VC2012 und gcc absolut fehlerfrei:#include <iostream> using namespace std; struct test { void foo() { std::cout << "foo\n"; } void foo() const { std::cout << "foo const\n"; } }; template< typename Ret, typename... Args, typename C > void do_const( Ret (C::*func)(Args... ) const) { test t; (t.*func)(); } template< typename Ret, typename... Args, typename C > void do_nonconst( Ret (C::*func)(Args... )) { test t; (t.*func)(); } int main() { do_const( &test::foo ); do_nonconst( &test::foo ); return 0; }Allerdings hat für mich vorhin alles so ausgesehen, als würde 2013RC genau hier bei do_const eine Mehrdeutigkeit anmäkeln, darum habe ich mich hier gemeldet. Ich kann das erst morgen wieder nachprüfen, leider.
-
Darf ich fragen wozu du das verwenden willst?
Bitte nicht falsch verstehen, ich will nicht rumnörgeln, ist reine Neugier.
-
Klar,
das ist Teil von meinem luabind-fork (https://github.com/decimad/luabind-deboostified). Vereinfacht (soll vereinfachen) die Definition von Methoden, die eben als const und als non-const vorhanden sind, wo man zur Zeit halt "per Hand" casten und dafür die ganze Signatur ausschreiben muss.Viele Grüße
-
Okay, weiter umgeschrieben und volles Testprogramm:
#include <iostream> class test_class { public: void test(int) const { std::cout << "const\n"; } void test(int) { std::cout << "nonconst\n"; } }; template<typename FnType> int def(FnType fn) { test_class t; (t.*fn)(4); return 2; } template< typename... Args > struct meth_cast { template< typename Class, typename Ret > static auto cast_const( Ret(Class::*fn)(Args...) const )-> decltype(fn) { return fn; } template< typename Class, typename Ret > static auto cast_nonconst( Ret(Class::*fn)(Args...) ) -> decltype(fn) { return fn; } }; int main(int argc, char* argv[]) { std::cout << def(meth_cast<int>::cast_const(&test_class::test)) << def(meth_cast<int>::cast_nonconst(&test_class::test)); return 0; }Sowohl VC2013 als auch GCC auf Ideone.com geben aus:
nonconst
constIrgendwas verpeile ich doch hier extrem maximal?
-
Wenn man an eine Sache denkt, dann ist das Problem ein anderes... das funktioniert schon genau richtig so, man sollte sich nur Gedanken darüber machen, in welcher Reihenfolge Funktionsargumente ausgewertet werden

Sorry für das Rauschen hier
-
Und das Problem aus meinem OP war auch gar keines, der Code funktionierte wunderbar. Nur hat IntelliSense vom 2013RC einen Bug, der den Code als fehlerhaft markiert, obwohl der Compiler ihn schluckt. Hab' ich mal gemeldet - aber ich sollte mich wohl sowieso nicht so sehr auf IntelliSense verlassen...
Viele Grüße & einen schönen Tag noch!
-
Hab' ich mal gemeldet - aber ich sollte mich wohl sowieso nicht so sehr auf IntelliSense verlassen...
Ja, es ist allgemein bekannt dass IntelliSense viele false positives liefert. Daher: Gerade bei C++11 & co. einfach ignorieren.