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_stringify

    Bei 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.


Anmelden zum Antworten