用于验证的可变参数模板

Variadic template for validation

我有一个 class,它最初尝试从配置中读取设置,如果值无效,则应使用默认值填充它们。

这是我得到的(自定义 Optional 实现):

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));
    }
}

调用方法时(默认为uint32_t类型):

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

发生此错误:

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

我不明白,为什么它不将 clamped 视为可行的重载?

MRE:https://godbolt.org/z/EWcnsE559

&clamped 不是有效的函数指针。

由于clamped是一个模板函数,你需要用一个有效的模板参数实例化,这样你才能得到函数指针。

例如:

readOrPopulateDefault(20, &clamped_validator<int>, Optional<int>(0), Optional<int>(12));
//                        ^^^^^^^^^^^^^^^^^^^^^^^^ ---> provide the template type!

提供一个即可解决问题:See Live