【问题标题】:Ambiguous call to overloaded function 'pow'对重载函数“pow”的模糊调用
【发布时间】:2014-09-05 03:32:14
【问题描述】:

我在运行以下代码时遇到了一些问题。我得到了这个:错误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 ==========

我该如何解决这个问题?谢谢。

【问题讨论】:

  • 你在这里根本不需要pow(),你可以使用移位,因为你是在取2的幂。
  • 这是被编译为 C++ 的 C 代码。您的编译器只是有一点分离性身份障碍。选择一种语言并坚持下去。
  • @Stefan:您应该尝试将#include &lt;math.h&gt; 更改为#include &lt;cmath&gt;。这可能会导致 pow()C++11 重载采用整数参数。
  • @Blastfurnace 很棒的提示!为什么不回答呢?

标签: c++ function overwrite pow


【解决方案1】:

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) { 

【讨论】:

  • 更有趣的问题是 VC++ 在这里所做的是否符合要求,因为如果你在 gcc 或 clang 上编译(修复其他两个错误)没有错误。
【解决方案2】:

尽管您将问题标记为 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”

【讨论】:

    【解决方案3】:

    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);
    

    其中Type1Type2arithmetic types

    【讨论】:

      【解决方案4】:

      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))
      

      还注意到 在您给定的代码 sn-p 中存在 Perreal 指出的错误

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

      你不能用字符串文字做算术运算。像 Ptefan 提到的那样改变它 ,也改变 int resultdouble result 如果您需要高精度和准确的结果。

      【讨论】:

        猜你喜欢
        • 2016-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-11
        • 2011-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多