簡體   English   中英

如果constexpr和C4702(以及C4100和C4715)

[英]if constexpr and C4702 (and C4100, and C4715)

有沒有辦法解決以下問題:

此代碼生成C4702警告“無法訪問的代碼”(在VC ++ 15.8上使用/std:c++17

template <typename T, typename VariantType>
inline bool MatchMonostate( VariantType& variant )
{
    SUPPRESS_C4100( variant );
    if constexpr ( std::is_same_v<T, std::monostate> )
    {
        variant = std::monostate();
        return true;
    }
    return false;  // !!! unreachable if the above is true !!! => C4702
}

為了抑制C4100'未引用的形式參數'警告,我已經在使用這個技巧了

#define SUPPRESS_C4100(x) ((void)x)

添加的簡單想法

    else
    {
        return false;
    }

導致警告C4715'並非所有控制路徑都返回值'。

它是無法訪問的,因為對於基於模板參數的模板的給定擴展,函數將傳遞條件並返回true fail並返回false。 沒有任何情況下它可以采用相同類型的任何一種方式。 它本質上是擴展到

if (true) {
  return true;
}
return false; // Obviously will never happen

我重寫它只有一個return語句。

template <typename T, typename VariantType>
inline bool MatchMonostate( VariantType& variant )
{
    SUPPRESS_C4100( variant );
    bool retval = false;
    if constexpr ( std::is_same_v<T, std::monostate> )
    {
        variant = std::monostate();
        retval = true;
    }
    return retval;
}

此外,在條件為真的情況下,變體不是未使用的。 您可能希望將禁止警告的行(基本上變為(void)變量)移動到else語句。

作為直接問題的直接答案。 關於if constexpr的主題。 考慮一下:

template <typename T, typename ... params >
 inline bool match_monostate
  (std::variant<params ...> & variant) noexcept    
{
 if constexpr (std::is_same_v<T, std::monostate>)
 {
     variant = std::monostate{} ;
 //  compiles only if called with variant
 //  whose one alternative is std::monostate
     return true;
 }
 else {
    return false;
 }
}

根據if constexpr表達式的bool結果,編譯器實際上產生了兩個函數。 if constexpr()產生true,則生成此版本:

  template <typename T, typename ... params >
 inline bool 
 match_monostate  (std::variant<params ...> & variant)  noexcept
{
    variant = std::monostate{} ;
//  compiles only if called with variant
//  whose one alternative is std::monostate
    return true;
}

if constexpr()產生false,則生成此版本:

template <typename T, typename ... params >
 inline bool 
 match_monostate  (std::variant<params ...> & variant)  noexcept
{
    return false;
}

第二個版本可能會發出有關未使用參數的警告。 但是(似乎)如果使用最新版本的clang / gcc / msvc則不行。 對於較舊的編譯器,“old123987”也指出可以將標准屬性添加到簽名中。 像這樣:

 template <typename T, typename ... params >
 inline bool 
 match_monostate  ([[maybe_unused]] std::variant<params ...> & variant) ;

這將阻止警告發出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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