std::abs的模板版本 列出了C++中的代码> STD::ABS的当前重载。我想知道为什么不定义下面的模板,并放弃所有丑陋的C风格重载 template <typename T> inline T abs(const T& v) { return v < 0 ? -v : v; } 模板内联 T abs(const T&v){return v

std::abs的模板版本 列出了C++中的代码> STD::ABS的当前重载。我想知道为什么不定义下面的模板,并放弃所有丑陋的C风格重载 template <typename T> inline T abs(const T& v) { return v < 0 ? -v : v; } 模板内联 T abs(const T&v){return v,c++,templates,cmath,C++,Templates,Cmath,因为类型“T”可以访问任何数据类型,包括char。那么,如果有人将字符传递给abs函数,您期望得到什么呢 这遇到了匹配所有内容的常见问题 abs有意义但此实现不复杂的类型示例请参见。目前,如果x和y未签名,std::abs(x-y) STD::Enable”,如果,你会得到一个错误,比如“候选模板被忽略了……”,这是非常描述性的。除了int,它只不过是8位。是的,NeilKirk,你是正确的,因为C++会做ASCII值操作,我们会得到结果。但这不是最终用户想要的输出。不,C++不会做“ASCII

因为类型“T”可以访问任何数据类型,包括char。那么,如果有人将字符传递给abs函数,您期望得到什么呢

这遇到了匹配所有内容的常见问题


abs
有意义但此实现不复杂的类型示例请参见。目前,如果
x
y
未签名,
std::abs(x-y)<2
将失败。这捕捉到了一个微妙的编程错误。根据提议的修改,它进行了编译,但在这方面做得完全错误
abs(3u-4u)
会比2大很多,事实上它是
UINT\u MAX

,什么是
abs
abs
?@MariusBancila那么它就不会编译为不兼容的类型。我也想知道这个问题的答案。作为模板,它将允许abs使用您自己的类,这些类支持适当的运算符。@Columbo,为什么不呢?@MariusBancila:将字符串与整数进行比较不会编译,但无疑会给出无法理解的错误消息。但是,你可以添加一些代码,比如“代码> STD::Enable”,如果,你会得到一个错误,比如“候选模板被忽略了……”,这是非常描述性的。除了int,它只不过是8位。是的,NeilKirk,你是正确的,因为C++会做ASCII值操作,我们会得到结果。但这不是最终用户想要的输出。不,C++不会做“ASCII”操作。毫无疑问,它将进行数字操作。事实上,最大的问题是
char
可能是无符号的,这会产生意想不到的结果(!)使用char类型保存8位数据也是很常见的,而且,没有任何替代方法,至少在过去没有。然而,在
char
上执行abs的有用性值得怀疑,因为它的符号是由实现定义的。对于复数,有一个
std::abs
重载,可以通过重载解析找到,并且是首选的,因为它更专业(在偏序方面)比上述内容更重要。@Columbo:它确实回答了为什么不能消除所有当前重载的问题。@M您可以将模板专门用于复杂类型。@Columbo:重点不是说
Complex
不能按原样工作:重点是要证明OP中的定义对于合理类型来说可能是完全错误的。类似的用户定义类型将无法编译(或者更糟糕的是,默默地编译一个错误的实现)。@Hurkyl我没有试图批评你的答案,这更多的是一个旁注-此模板和重载(例如,
complex
配合得很好:)@MohitJain
0u-1u==UINT\u MAX
,以及
UINT\u MAX==2^(无论什么)-1
。这是一个很好的例子,第2192期是一本有趣的读物。
std::abs(3u-4u)
编译。请看。我仍然不明白为什么整数类型的重载返回一个
double
,而不是原来的整数类型。@Lingxi:错误的页面。或者看看更好的网站: