g++ 错误:重载“abs(unsigned int)”的调用不明确

Luk*_*tas 3 c++ compiler-errors g++ std

我正在尝试编译以下代码:

#include <stdlib.h>
static
unsigned iSqr( unsigned i )
{
    unsigned res1 = 2;
    unsigned res2 = i/res1;
    while( abs( res1 - res2 ) > 1 )
        {
        res1 = (res1 + res2)/2;
        res2 = i/res1;
        }
    return res1 < res2 ? res1 : res2;
}
Run Code Online (Sandbox Code Playgroud)

使用g++ test.cc -o test

但是,g++ 编译器失败并出现以下错误:

test.cc: In function 'unsigned int iSqr(unsigned int)':                                         
test.cc:8:29: error: call of overloaded 'abs(unsigned int)' is ambiguous                        
     while( abs( res1 - res2 ) > 1 )            
                             ^                  
In file included from /usr/include/c++/6/cstdlib:75:0,                                          
                 from /usr/include/c++/6/stdlib.h:36,                                           
                 from test.cc:2:                
/usr/include/stdlib.h:735:12: note: candidate: int abs(int)                                     
 extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur;                            
            ^~~         
In file included from /usr/include/c++/6/stdlib.h:36:0,                                         
                 from test.cc:2:                
/usr/include/c++/6/cstdlib:185:3: note: candidate: __int128 std::abs(__int128)                  
   abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }                            
   ^~~                  
/usr/include/c++/6/cstdlib:180:3: note: candidate: long long int std::abs(long long int)        
   abs(long long __x) { return __builtin_llabs (__x); }                                         
   ^~~                  
/usr/include/c++/6/cstdlib:172:3: note: candidate: long int std::abs(long int)                  
   abs(long __i) { return __builtin_labs(__i); }                                                
   ^~~     
Run Code Online (Sandbox Code Playgroud)

为什么会发生此错误以及如何修复它?

g++版本是:gcc版本6.3.0

陳 力*_*陳 力 6

abs<stdlib.h>(自c++11起):http://www.cplusplus.com/reference/cstdlib/abs/

          int abs (          int n);
     long int abs (     long int n);
long long int abs (long long int n);
Run Code Online (Sandbox Code Playgroud)

如果出现以下情况,调用将会不明确重载决策无法选择比此类不可微函数更好的调用匹配,则该调用

您可以显式地转换参数,如下所示:

static_cast<int>(res1 - res2)
Run Code Online (Sandbox Code Playgroud)


Kha*_*med 5

您可以将结果转换为带符号的数据类型,以便abs知道您正在调用哪个数据类型,如下所示:

while( abs( int(res1 - res2) ) > 1 )
Run Code Online (Sandbox Code Playgroud)

但再次考虑一下你需要在这里做什么,因为对无符号进行减运算的结果仍然是无符号的,所以如果结果低于 0 它将变成一个很大的数字(作为正常的溢出),所以我认为使用有符号变量是首先解决问题的最佳方法

int iSqr( unsigned i )
{
    int res1 = 2;
    int res2 = i/res1;
    while( abs(res1 - res2) > 1 )
    {
        res1 = (res1 + res2)/2;
        res2 = i/res1;
    }
    return res1 < res2 ? res1 : res2;
}
Run Code Online (Sandbox Code Playgroud)