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 do not get, why it does not consider clamped
as a viable overload?
The &clamped
is not a valid function pointer.
Since the clamped
is a template function, you need to instantiate with a valid template argument so that you can get the function pointer.
For example:
readOrPopulateDefault(20, &clamped_validator<int>, Optional<int>(0), Optional<int>(12));
// ^^^^^^^^^^^^^^^^^^^^^^^^ ---> provide the template type!
Providing one will solve the issue: See Live