samedi 24 juillet 2021

C++ variadic template for validation

I have a class which initially tries to read settings from a configuration and if the values are invalid, they should be populated with a default. This is what I got (custom Optional implementation):

    template <typename T>
    struct dont_deduce { using type = T; };

    template <typename T>
    using dont_deduce_t = typename dont_deduce<T>::type;

    template<typename T>
    static bool clamped(const T& val, const Optional<T>& lower, const Optional<T>& upper){
        if(lower.has_value() && val < lower.value())
            return false;
        if(upper.has_value() && val > upper.value())
            return false;
        return true;
    }

    template <typename X, typename ... PP>
    inline void readSettingOrPopulateDefault(X& property, const QString& key, X default_val, QSettings& settings, std::function<bool(dont_deduce_t<X>, dont_deduce_t<PP> &&... pp)> validator, PP &&... pp) const{
        property = qvariant_cast<X>(settings.value( key, QVariant()));
        if (!validator(property, std::forward(pp) ...))
        {
            property = default_val;
            settings.setValue(key, QVariant(property));
        }
    }

when calling the method (default is of type uint32_t):

 readSettingOrPopulateDefault(m_query_interval_sec, KEY_QUERYINTERVAL, DEFAULT_QUERY_INTERVAL, settings, &clamped, Optional<uint32_t>(0),  Optional<uint32_t>());

this error occurs:

error: no matching member function for call to 'readSettingOrPopulateDefault'
note: candidate function [with X = unsigned int, PP = <Optional<unsigned int>, Optional<unsigned int>>] not viable: no overload of 'clamped' matching 'std::function<bool (dont_deduce_t<unsigned int>, dont_deduce_t<Optional<unsigned int>> &&, dont_deduce_t<Optional<unsigned int>> &&)>' (aka 'function<bool (unsigned int, Optional<unsigned int> &&, Optional<unsigned int> &&)>') for 5th argument

I don't get why it does not consider clamped as a viable overload.

Aucun commentaire:

Enregistrer un commentaire