[英]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.