Разве компилятор Visual Studio 2008 не выполняет автоматическую настройку double с помощью sqrt в C ++?

StackOverflow https://stackoverflow.com/questions/2452510

  •  20-09-2019
  •  | 
  •  

Вопрос

Разве компилятор не должен автоматически приводить к двойному в следующем?По крайней мере, по словам Уолтера Сэвича.

#include <iostream>
#include <cmath>
using namespace std;

int main(){
    int k;
    for(k = 1; k <= 10; k++)
        cout << "The square root of k is: " << sqrt(k) << endl;
    return 0;
}//error C2668: 'sqrt' : ambiguous call to overloaded function
//Visual Studio 2008 on Win Vista
Это было полезно?

Решение

Проблема в том, что существует три версии sqrt на выбор:

     double sqrt (      double x );
      float sqrt (       float x );
long double sqrt ( long double x );

Поскольку вы проходите в int, компилятор будет продвигать ваш аргумент, но в равной степени допустимо продвигать ваше целое число к любому из вышеперечисленных типов, так что это неоднозначно.

Вы можете исправить это, просто явно приведя к одному из вышеуказанных типов, как в:

cout << "The square root of k is: " << sqrt((double)k) << endl;

Другие советы

Ошибка неоднозначного вызова заключается в том, что он не знает, какую функцию вызывать, а не в том, что она не преобразуется неявно.

посмотрите на следующее.Если я создам свою собственную функцию, которая принимает double и возвращает double, у нее не возникнет проблем с неявным преобразованием.Поскольку ваше целое число может быть преобразовано в любую из трех перегрузок, оно не знает, что вызывать.

double mysqrt(double d)
{
   return d;
}
using namespace std;
int main(int argc, char ** argv)
{

    int k;
    for(k = 1; k <= 10; k++)
        cout << "The square root of k is: " << mysqrt(k) << endl;
    return 0;
}//Works Fine

Однако, если я добавлю другую версию mysqrt, которая принимает значение с плавающей точкой, я создам неоднозначную ошибку вызова.

double mysqrt(float f)
{
    return f;
}
double mysqrt(double d)
{
    return d;
}
using namespace std;
int main(int argc, char ** argv)
{

    int k;
    for(k = 1; k <= 10; k++)
        cout << "The square root of k is: " << mysqrt(k) << endl;
    return 0;
}//error C2668: 'mysqrt' : ambiguous call to overloaded function

Поскольку существует множество функции sqrt (перегружает) и более 1 могут принимать int в качестве параметра без потери точности, вам решать, какой именно (и это хорошо, потому что вы не хотите, чтобы компилятор принимал решения за вас на основе "косвенных" доказательств - передавая int в sqrt).

C всегда возвращает двойную версию, если только не вызывается sqrtf.

Попробуйте выполнить свой вызов с помощью (double)

Из MSDN:[

double sqrt(
   double x 
);
float sqrt(
   float x 
);  // C++ only
long double sqrt(
   long double x
);  // C++ only
float sqrtf(
   float x 
);

]1

Существует несколько перегрузок для std::sqrt в cmath.Один берет float, а другой - double.Компилятор не может знать, какой из них вы хотите вызвать, и целые числа могут быть преобразованы в любой из них.

При отсутствии дополнительных перегрузок он автоматически преобразуется в double [это имеет место в C], как вы и ожидали.

Да, он должен автоматически преобразовываться из int в double.g ++ компилирует это нормально, так что я думаю, VS ошибается

Редактировать:не уверен, почему мой ответ отклонен.Но я думаю, что во время перегрузки функций в c ++ автоматическое преобразование всегда должно происходить с максимально возможным типом данных при автоматическом преобразовании.для бывших:если есть возможность преобразовать из into в long, float и double, она всегда должна выполнять преобразование int в double .

Я попробовал это в g ++, и это вызывает функцию sqrt (double).

#include <iostream>
#include <cmath>
#include <typeinfo>
using namespace std;

int main(){
    int k;
    for(k = 1; k <= 10; k++)
        cout << "The square root of k is: " << sqrt(k) <<' '<<  typeid(sqrt(k)).name()<< endl;
    return 0;
}

Таким образом, вывод typeid() равен "d", что означает, что он выполнил автоматическое преобразование из int в double.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top