繁体   English   中英

对重载函数'pow'的模糊调用

[英]Ambiguous call to overloaded function 'pow'

我在运行以下代码时遇到了一些问题。 我得到了这个:错误C2668:'pow':对重载函数的模糊调用。 我试图使用static_cast手动将参数转换为适当的类型,但是我想我得到一些指针错误?!

该程序应将数字从基数16转换为基数10。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>

//base 16 to base 10

int convert(char *n){
    int result = 0;
    for (int i = strlen(n) - 1; i >= 0; i--){
        if (n[i] >= 'a')
            result += (n[i] - 'a' + 10)* pow(16, strlen(n) - i - 1);
        else
        if (n[i] >= 'A')
            result += (n[i] - 'A' + 10)* pow(16, strlen(n) - i - 1);
        else
        if (n[i] >= '0')
            result += (n[i] - '0')* pow(16, strlen(n) - i - 1);
    }
    return result;
}

void main(void){
    char n[10];
    printf("Introduceti numarul: "); scanf("%s", n);
    printf("Numarul in baza 10 este: %d", convert(n));
    _getch();
}

这些都是错误。

1>------ Build started: Project: pr8, Configuration: Debug Win32 ------
1>  pr8.cpp
1> error C2668: 'pow' : ambiguous call to overloaded function
1> could be 'long double pow(long double,int) throw()'
1> or       'long double pow(long double,long double) throw()'
1> or       'float pow(float,int) throw()'
1> or       'float pow(float,float) throw()'
1> or       'double pow(double,int) throw()'
1> or       'double pow(double,double)'
1>          while trying to match the argument list '(int, size_t)'
1>'-' : pointer can only be subtracted from another pointer
1> error C2668: 'pow' : ambiguous call to overloaded function
1> could be 'long double pow(long double,int) throw()'
1> or       'long double pow(long double,long double) throw()'
1> or       'float pow(float,int) throw()'
1> or       'float pow(float,float) throw()'
1> or       'double pow(double,int) throw()'
1> or       'double pow(double,double)'
1>          while trying to match the argument list '(int, size_t)'
1> error C2668: 'pow' : ambiguous call to overloaded function
1> could be 'long double pow(long double,int) throw()'
1> or       'long double pow(long double,long double) throw()'
1> or       'float pow(float,int) throw()'
1> or       'float pow(float,float) throw()'
1> or       'double pow(double,int) throw()'
1> or       'double pow(double,double)'
1>          while trying to match the argument list '(int, size_t)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

我怎样才能解决这个问题? 谢谢。

strlen返回类型是C ++中的size_t 所以你可以通过铸造解决歧义:

pow(static_cast<size_t>(16), strlen(n) - i - 1);

也在这里:

result += (n[i] - "A" + 10)

                  ^ this should be 'A'

main应该返回int而不是void

int main(void) { 

虽然您将问题标记为C问题,但实际上您将程序编译为C ++程序,因为它是允许重载函数的C ++。

在您的情况下,C ++编译器无法选择适当的重载函数pow。 错误消息clear显示编译器考虑的功能。 要消除歧义,您可以通过以下方式调用该函数

result += (n[i] - 'a' + 10)* pow( 16.0, strlen(n) - i - 1.0 );

在这种情况下,编译器将使用函数

double pow(double,double)

考虑到在C / C ++函数中main应该有返回类型int

在C中,函数定义为

int main( void ) {

而在C ++中,它通常被定义为

int main() {

我认为有一个错字

    if (n[i] >= 'A')
        result += (n[i] - "A" + 10)* pow(16, strlen(n) - i - 1);

而不是字符串文字“A”应该有字符文字'A'

C语言中,我们可以在math.h下找到库函数:

double pow(double x, double y) ---- 1**

C ++语言中,我们可以在cmath下设置一组重载函数,例如:

float       pow( float base, float exp ) ---- 2
double      pow( double base, double exp ) ---- 3
long double pow( long double base, long double exp ) ---- 4
float       pow( float base, int iexp ) ---- 5
double      pow( double base, int iexp ) ---- 6
long double pow( long double base, int iexp ) ---- 7

由于您使用C风格编程但使用C ++编译器编译,编译器可能会遇到数学库中具有已定义函数的歧义状态,因此您应该根据上面提到的函数定义1适当地转换您的参数,因此将代码更改为,

result += (n[i] - 'a' + 10)* pow(16.0, static_cast<double>(strlen(n) - i - 1))

与你给出的代码片段风陵渡有一个错误,因为Perreal注意

if (n[i] >= 'A')
            result += (n[i] - "A" + 10)* pow(16, strlen(n) - i - 1);

你不能用字符串文字进行算术运算。如Ptefan所提到的那样改变 ,如果你需要高精度和准确的结果,也可以将int result改为double result结果。

C ++ 98提供了以下pow重载版本:

     double pow (double base     , double exponent);
      float pow (float base      , float exponent);
long double pow (long double base, long double exponent);
     double pow (double base     , int exponent);
long double pow (long double base, int exponent);

您正在使用的第一个参数16可以转换为这些函数中使用的第一个参数的任何类型。 因此,编译器无法解决歧义。 您可以通过指定其类型来明确第一个参数来解决歧义。 以下任何一项都应该有效:

pow(16.0, strlen(n) - i - 1);
pow(16.0f,  strlen(n) - i - 1);
pow(16.0l,  strlen(n) - i - 1);

如果您能够使用C++11 ,则可以使用现有代码。 它有一个过载:

double pow (Type1 base      , Type2 exponent);

其中Type1Type2算术类型

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM