2014-07-15 21 views
6

Sto riscontrando alcuni problemi durante l'esecuzione del seguente codice. Ho capito: errore C2668: 'pow': chiamata ambigua a funzione sovraccaricata. Ho provato a trasmettere manualmente gli argomenti al tipo appropriato usando static_cast, tuttavia penso di avere qualche errore puntatore ?!Chiamata ambigua a funzione sovraccaricata 'pow'

Il programma deve convertire un numero da base 16 basare 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(); 
} 

Questi sono tutti gli errori.

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

Come posso risolvere questo? Grazie.

+0

Non hai davvero bisogno di 'pow()' qui, potresti usare i turni, dato che stai esponenziando una potenza di due. – EJP

+0

Questo è il codice C che viene compilato come C++. Il tuo compilatore ha solo un piccolo disturbo dissociativo dell'identità. Scegli una lingua e attenersi ad essa. –

+1

@Stefan: dovresti provare a cambiare la riga che dice '#include ' a '#include '. Questo potrebbe sollevare il sovraccarico di 'C++ 11' di' pow() 'che prende argomenti integrali. – Blastfurnace

risposta

2

strlen tipo di ritorno è size_t in C++. Così si può risolvere l'ambiguità via casting:

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

anche qui:

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

       ^this should be 'A' 

e principale dovrebbe tornare int invece di void:

int main(void) { 
+1

Il problema più interessante è se ciò che VC++ sta facendo qui è conforme, poiché non c'è errore se si compila questo (con gli altri due errori corretti) su gcc o clang. –

+0

Ciao! Sto ancora ricevendo gli stessi errori. – Stefan

3

Anche se hai segnato la tua domanda come C domanda che in realtà compili il tuo programma come un programma C++ perché è C++ che permette di sovraccaricare le funzioni.

Nel tuo caso il compilatore C++ non è in grado di selezionare una funzione di sovraccarico appropriata. Il messaggio di errore chiaro mostra quali funzioni considera il compilatore. Per rimuovere l'ambiguità che si potrebbe chiamare la funzione per esempio seguente modo

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

In questo caso il compilatore avrebbe usato la funzione

double pow(double,double) 

tener conto che in C/C++ funzione principale deve avere tipo di ritorno int.

In C la funzione è definita come

int main(void) { 

mentre in C++ che viene solitamente definita come

int main() { 

E penso che ci sia un errore di battitura

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

Invece del stringa letterale "A" ci sarà carattere letterale "A"

0

C++ 98 fornisce le seguenti versioni di overload di 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); 

Il primo argomento che si sta utilizzando, 16, possono essere convertiti in uno qualsiasi dei tipi di primi argomenti utilizzati in tali funzioni. Quindi, il compilatore non può risolvere l'ambiguità. È possibile risolvere l'ambiguità esplicitando con il primo argomento, specificandone il tipo.Qualsiasi una delle seguenti dovrebbe funzionare:

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

Se siete in grado di utilizzare C++11, è possibile utilizzare il codice esistente. Ha un sovraccarico:

double pow (Type1 base  , Type2 exponent); 

dove Type1 e Type2 sono arithmetic types.

4

In C lingua possiamo trovare funzione di libreria sotto math.h:

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

In C++ linguaggio che in grado di avere un insieme di funzioni sovraccaricate sotto cmath come ad esempio:

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 

Poiché si utilizzava la programmazione in stile C ma compilato utilizzando il compilatore C++, compilatore potrebbe trovarsi ad affrontare con gli Stati ambiguità con la funzione definita nella libreria matematica, quindi, è necessario convertire il vostro argomento in modo appropriato in base alla definizione di funzione come detto sopra, quindi modificare il codice come,

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

anche osservato con nel dato frammento di codice c'è un errore come Perreal notato

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

non si può fare operazioni aritmetiche con lo spago literals.change come Ptefan menzionato , cambia anche int result-double result se avete bisogno di alta precisione e risultati accurati.