是否可以解决以下问题:
此代码会生成C4702警告“无法访问的代码”(在VC ++ 15.8上,带有class invoice(models.Model):
customer = models.CharField(max_length=256, blank=False)
date = models.DateField(default=now)
invoice_number = models.IntegerField(editable=False,default=1)
total_quantity = models.DecimalField(max_digits=10, decimal_places=2)
total_amount = models.DecimalField(max_digits=10, decimal_places=2)
total_tax = models.DecimalField(max_digits=10, decimal_places=2)
def save(self):
if self._state.adding:
last_invoice=invoice.objects.all().aggregate(largest=models.Max('invoice_number'))['largest']
if last_invoice is not None:
self.invoice_number=last_invoice+1
super(invoice,self).save()
)
/std:c++17
为了消除C4100“未引用的形式参数”警告,我已经在使用技巧了
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
}
添加的简单想法
#define SUPPRESS_C4100(x) ((void)x)
产生警告C4715,“并非所有控制路径都返回值”。
答案 0 :(得分:6)
这是无法实现的,因为对于基于模板参数的给定模板扩展,该函数将仅 通过条件并返回true,否则返回,否则失败并返回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;
}
此外,在条件为true的情况下, not 未使用。您可能希望将抑制警告(基本上变成(void)变量)的行移到else语句。
答案 1 :(得分:1)
作为直接问题的直接答案。关于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
表达式的布尔结果,编译器实际上产生两个函数。当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) ;
这将停止发出警告。