[英]Use Template of binary predicate function as parameter (std::greater, std::equal_to ) C++
[英]C++ template instance as function parameter and lambda binary predicate
我正在修復我的項目中的一些聲納雲問題。 一個投訴是 function,我在其中讀取並反序列化了我的應用程序的設置。 基本上在一個 function 中有 50 個左右的塊:
if (!m_logLevel.deserializeFromSettings(settings, HGGW_KEY_LOGLEVEL) || m_logLevel.value() <= 0 || m_logLevel.value() > 4)
{
m_logLevel.update(HGGW_DEFAULT_LOGLEVEL, 0);
m_logLevel.serializeToQSettings(settings, HGGW_KEY_LOGLEVEL);
}
成員是模板化 class 的實例:
template <typename T>
class AwsProperty
{
public:
AwsProperty(T value, qint64 timestamp) : m_timestamp(timestamp), m_data(value){}
//other stuff, not important
}
//example:
AwsProperty<int> m_property;
我試圖設計這個 function:
template <typename X>
void readAWSSettingOrPopulateDefault(AwsProperty<X> property, QString key, X default_val, QSettings settings, bool (*predicate)(X)){
if(!property.deserializeFromSettings(settings,key) || predicate(property.value())){
property.update(default_val, 0);
property.serializeToQSettings(settings, key);
}
}
試圖調用它:
this->readAWSSettingOrPopulateDefault(m_logLevel, HGGW_KEY_LOGLEVEL, HGGW_DEFAULT_LOGLEVEL, settings, [](int val){return val <= 0 || val > 4;});
產生此錯誤:
XXXXconfig.cpp:275: error: no matching function for call to ‘LocalConfig::readAWSSettingOrPopulateDefault(HGGWAwsPropertyInt32&, const QString&, const int&, QSettings&, LocalConfig::init(QString)::<lambda(int)>)’
this->readAWSSettingOrPopulateDefault(m_logLevel, HGGW_KEY_LOGLEVEL, HGGW_DEFAULT_LOGLEVEL, settings, [](int val){return val <= 0 || val > 4;});
XXXXconfig.cpp:275: note: mismatched types ‘bool (*)(X)’ and ‘LocalConfig::init(QString)::<lambda(int)>’
this->readAWSSettingOrPopulateDefault(m_logLevel, HGGW_KEY_LOGLEVEL, HGGW_DEFAULT_LOGLEVEL, settings, [](int val){return val <= 0 || val > 4;});
^ ^
XXXXconfig.cpp:275: note: mismatched types ‘bool (*)(X)’ and ‘LocalConfig::init(QString)::<lambda(int)>’
^
您的代碼報告錯誤的原因是對於聲明為的 function 模板:
template <typename X>
void readAWSSettingOrPopulateDefault(AwsProperty<X> property, QString key
, X default_val, QSettings settings
, bool (*predicate)(X));
編譯器必須使用這個模板參數property
、 default_val
和predicate
從所有 arguments 中推導出X
,然后確保這些推導的類型相同(也就是說,只有一個模板參數,它可以保存一種類型) .
但是,lambda不是function。 它可以通過隱式轉換轉換為 function 指針。 模板參數推導不考慮轉換(派生到基轉換除外)。 因此,編譯器無法完成模板參數推導。
為了使您的代碼正常工作,請將最后一次出現的X
放在 function 指針類型參數聲明中的非推導上下文中:
template <typename T>
struct dont_deduce { using type = T; };
template <typename T>
using dont_deduce_t = typename dont_deduce<T>::type;
template <typename X>
void readAWSSettingOrPopulateDefault(AwsProperty<X> property, QString key
, X default_val, QSettings settings
, bool (*predicate)(dont_deduce_t<X>));
這樣,編譯器甚至不會嘗試從 lambda 表達式中推斷出X
,而是使用property
/ default_val
中的類型,從而可以使用 lambda 到 ZC1C425Z4074C 指針的隱式轉換。 即不推演,同時有一個已知的可以觸發轉換的function簽名。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.