用于验证的可变参数模板
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
视为可行的重载?
&clamped
不是有效的函数指针。
由于clamped
是一个模板函数,你需要用一个有效的模板参数实例化,这样你才能得到函数指针。
例如:
readOrPopulateDefault(20, &clamped_validator<int>, Optional<int>(0), Optional<int>(12));
// ^^^^^^^^^^^^^^^^^^^^^^^^ ---> provide the template type!
提供一个即可解决问题:See Live
我有一个 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
视为可行的重载?
&clamped
不是有效的函数指针。
由于clamped
是一个模板函数,你需要用一个有效的模板参数实例化,这样你才能得到函数指针。
例如:
readOrPopulateDefault(20, &clamped_validator<int>, Optional<int>(0), Optional<int>(12));
// ^^^^^^^^^^^^^^^^^^^^^^^^ ---> provide the template type!
提供一个即可解决问题:See Live