Разное поведение fmod (и других) под c ++ 11, по крайней мере в Visual Studio

У меня есть пример кода, который ведет себя по-разному в Visual C ++ 2012 с новыми заголовками C ++ 11, чем в VC ++ 2010. Это касается того, что происходит, когда вы вызываете функцию std :: fmod, которую вы получаете, когда вы включайте cmath, и когда передаваемые вами аргументы не являются двойными, а являются классами, которые имеют неявное преобразование в двойной оператор:

#include 

class Num {
double d_;
public:
Num(double d) : d_(d) {}

operator double() const { return d_; }
};

int main(int argc, char* argv[]) {
Num n1(3.14159265358979323846264338327950288419716939937510);
Num n2(2.0);

double result1 = fmod((double)n1, (double)n2);
double result2 = fmod((float)n1, (float)n2);
double result3 = fmod(n1, n2);

if (result2==result1) std::cout << "fmod(double, double) returns the same as fmod(float,float)" << std::endl;
if (result3==result1) std::cout << "fmod(Num, Num) returns the same as fmod(double,double)" << std::endl;
if (result3==result2) std::cout << "fmod(Num, Num) returns the same as fmod(float,float)" << std::endl;
}

Скорее к моему удивлению, это вызывает версию fmod, которая принимает два числа с плавающей запятой, а не версия fmod, которая принимает две двойные.

Итак, мой вопрос, это правильное поведение, учитывая стандарт C ++ 11? Единственная информация, которую я могу найти о поведении, находится в документации cppreference.com здесь , где написано (выделено мной):

Если какой-либо аргумент имеет целочисленный тип, он приводится удвоить. Если какой-либо другой аргумент является long double, тогда тип возвращаемого значения long double, в противном случае это double .

Однако реализация в заголовочных файлах Visual Studio, по-видимому, реализует «иначе это float».

Кто-нибудь знает, что это за намерения :-)?

Пропустив пример через онлайн-версию GCC для c ++ 11 (в противном случае у меня нет простого доступа к последней копии GCC) казалось бы, он называет «двойную» версию fmod, чего я наивно ожидаю.

Для ясности я использую

Оптимизирующий компилятор Microsoft (R) C / C ++ версии 17.00.51106.1 для x86

, который поставляется с

Microsoft Visual Studio Express 2012 для Windows Desktop Версия 11.0.51106.01, обновление 1

10
задан ildjarn 22 March 2013 в 20:45
поделиться