我在任何数据类型上都以统一为中心的重质步骤功能,我使用以下方式编码了:
template <typename T>
int h1(const T& t){
if (t < 1){
return 0;
} else if (t >= 1){
return 1;
}
}
在代码审查中,我的审阅者告诉我,所有控制路径都没有明确的回报。而且编译器也不警告我。但是我不同意;条件是互斥的。我该如何处理?
这取决于模板的使用方式。对于int
,您可以。
但是,如果t
是IEEE754浮点double
类型,将值集为NaN
,则t < 1
和t >= 1
都不是true
,因此程序控制到达if
块的末端!这会导致函数在没有明确值的情况下返回;其行为不确定。
(在更普遍的情况下,T
以不涵盖所有可能性的方式将<
和>=
运算符重载,程序控制将到达if
块的末端,而没有显式return
。)
这里的故事的寓意是决定哪个分支应为默认值,并将其视为else
情况。
仅仅因为代码是正确的,这并不意味着它不能更好。正确执行是第一个质量的步骤,而不是最后一个。
if (t < 1) {
return 0;
} else if (t >= 1){
return 1;
}
与<
和>=
的SANE行为相比,t
的任何数据类型的"正确"是"正确的"。但这是:
if (t < 1) {
return 0;
}
return 1;
通过检查涵盖了每种情况,
更容易看到,并避免了第二个不需要的比较(某些编译器可能没有进行优化)。代码不仅是由编译器读取的,还由人类阅读,包括您十年后的代码。让人类休息一下,并为他们的理解而写更多。
如前所述,有些特殊数字可以是<
和>=
,因此您的评论者简直是正确的。
问题是:是什么让您首先要这样对此进行编码?您为什么还考虑为自己和他人(需要维护您的代码的人)如此艰难的生活?仅仅您足够聪明,可以推断出<
和>=
应该涵盖所有情况,这并不意味着您必须使代码比必要的更复杂。物理学的代码也适用于代码:使事情尽可能简单,但并不简单(我相信爱因斯坦说了这一点)。
考虑一下。您想实现什么?必须是这样的:'返回0如果输入小于1,则返回1否则返回1。"您所做的是通过说...哦,但这意味着如果T更大或相等,我会返回1。1。这种不必要的'x含义是y'需要代表维护者进行额外的思考工作。如果您认为这是一件好事,我建议自己进行几年的代码维护。
如果是我的评论,我会再发表评论。如果您使用" if"语句,那么您基本上可以在所有分支中做任何您想做的任何事情。但是在这种情况下,您不做"任何事情"。您要做的就是返回0或1,具体取决于T&lt; 1。在这些情况下,我认为'?:'语句比if
语句更好,更可读性。因此:
return t<1 ? 0 : 1;
我知道某些公司禁止使用?:
操作员,我发现这是一件可怕的事情。?:
通常与规格更好地匹配,并且它可以使代码更容易阅读(如果谨慎使用)...