auf applizierbare Funktionsüberladung prüfen
-
Ich habe eine Funktion, die sehr stark überladen ist und SFINAE exploitet, sodass sich die Balken biegen.
Die Funktion heit: js_stringifyBei containern wollte ich nun eine SFINAE condition hinzufügen, die generell prüft ob der value_type in js_stringify gestopft werden kann, selbes bei pointern (js_stringify(*ptr)) usw.
Ich habe nun angefangen alle bisherigen conditions zusammenzutragen.
(is_arithmetic, is_pointer (excl func_ptr), is_js_object (boost fusion vector), tuples, is_container, ... viele mehr)
Aber dann dachte ich mir, wenn ich einfach prüfen könnte, ob es für T eine geeignete "js_stringify"-Variante gibt, die T akzeptiert, hätte ich hier keine Code duplication mehr.)
-
Weiß nicht, vielleicht suchste sowas?
#include <iostream> #include <utility> using namespace std; void js_stringify(int){ } void js_stringify(char){ } template<typename T> class Test { template<typename U> static char check(...); template<typename U> static char (&check(decltype(js_stringify(declval<U>()))*))[2]; public: static const bool value=sizeof(check<T>(0))==2; }; int main(){ cout<< Test<int>::value <<'\n';js_stringify(1); cout<< Test<char>::value <<'\n';js_stringify('a'); cout<< Test<bool>::value <<'\n';js_stringify(true); cout<< Test<void*>::value <<'\n';//js_stringify(nullptr); }
-
Das sieht schonmal Spitze aus.
Ich teste das gleich mal im Hauptprojekt aus
-
EDIT: Ich bin grad selbst auf SFINAE reingefallen.
Läuft perfekt.Jetzt geht auch sowas cooles, wie:
namespace JSON { template <typename T> std::string js_try_stringify(std::string const& name, T const& obj, StringificationOptions const& options = DEFAULT_OPTIONS, typename std::enable_if <Internal::can_js_stringify<T>::value, void>::type* = nullptr) { return js_stringify(name, obj, options); } template <typename T> std::string js_try_stringify(std::string const&, T const&, StringificationOptions const& = DEFAULT_OPTIONS, typename std::enable_if <!Internal::can_js_stringify<T>::value, int>::type* = nullptr) { static_assert (Internal::can_js_stringify<T>::value, "the object you try to convert is not convertible to JSON"); return {}; } }
-
Das ist ein bisschen doppelt. Warum sollte man zweimal mit enable_if nachfragen, wenn die eine Version immer eine assertion auslöst.
namespace JSON { template <typename T> std::string js_try_stringify(std::string const& name, T const& obj, StringificationOptions const& options = DEFAULT_OPTIONS) { static_assert (Internal::can_js_stringify<T>::value, "the object you try to convert is not convertible to JSON"); return js_stringify(name, obj, options); } }
Das tut es doch auch.
-
Das ist zwar richtig, aber dann gibt er zusätzlich noch den Fehler, dass es keine passende js_stringify Funktion gibt und die Meldung ist sehr lang.