用于验证的可变模板

问题描述

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

这就是我得到的(自定义 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