C++ std::abs(0u)是否格式不正确?
鉴于以下计划:C++ std::abs(0u)是否格式不正确?,c++,c++11,language-lawyer,cmath,C++,C++11,Language Lawyer,Cmath,鉴于以下计划: #include <cmath> int main() { std::abs(0u) ; } 哪个结果是正确的?abs(0u)是否应该含糊不清 MSalters指出了一个有趣的相关问题:。看起来libstdc++是正确的,这不是格式错误,尽管我们会看到有人对这是否是LWG活动问题2192中的缺陷表示怀疑 C++11标准草案第26.8节第11段规定: 此外,应具有足够的额外过载,以确保: 并包括以下项目: 否则,如果与double参数对应的任何参数具有do
#include <cmath>
int main()
{
std::abs(0u) ;
}
哪个结果是正确的?abs(0u)是否应该含糊不清
MSalters指出了一个有趣的相关问题:。看起来
libstdc++
是正确的,这不是格式错误,尽管我们会看到有人对这是否是LWG活动问题2192
中的缺陷表示怀疑
C++11标准草案第26.8节第11段规定:
此外,应具有足够的额外过载,以确保:
并包括以下项目:
libstdc++
does案例:
由于子项目符号2(“[…]或
26.8[c.math]p11的整数类型[…]”)(请注意,当前
LWG 2086的解决方案无法解决此问题)
abs
因此当前的措辞表明libstdc++
是一致的,不清楚为什么libc++
选择了当前的实现。我找不到关于这个主题的bug报告和讨论,LWG问题也没有提到不同的实现
建议的解决方案将使std::abs(0u)
格式错误:
如果使用无符号整数类型的参数调用abs(),则
无法通过整型升级([conv.prom])将转换为int
程序格式不正确。[注意:可以升级为int的参数
允许与C兼容-结束注释]
虽然有些人可能会质疑将abs
与无符号类型一起使用的概念,但Howard Hinnant在报告中指出,当使用模板时,这种后果可能并不明显,并提供了一个示例:
……尤其是C++中,我们有模板,并且涉及的类型 在设计时,程序员并不总是很清楚。例如 考虑:
template <class Int>
Int
analyze(Int x, Int y)
{
// ...
if (std::abs(x - y) < threshold)
{
// ...
}
// ...
}
模板
Int
分析(整数x,整数y)
{
// ...
如果(标准::绝对值(x-y)<阈值)
{
// ...
}
// ...
}
template<typename _Tp>
inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
double>::__type
abs(_Tp __x)
{ return __builtin_fabs(__x); }
#include <type_traits>
#include <cmath>
static_assert(std::is_same<decltype(std::abs(0u)), double>(), "Oops");
int main() {
std::abs(0u); // Calls std::abs(double)
}
template <class Int>
Int
analyze(Int x, Int y)
{
// ...
if (std::abs(x - y) < threshold)
{
// ...
}
// ...
}