簡體   English   中英

C++ 模板實例作為 function 參數和 lambda 二進制謂詞

[英]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));

編譯器必須使用這個模板參數propertydefault_valpredicate從所有 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM