我有一些示例代码在 Visual C++ 2012 下使用新的 C++11 标头的行为与在 VC++ 2010 下的行为不同。它涉及调用包含 cmath 时获得的 std::fmod 函数时会发生什么,并且当您传递的参数不是双精度,而是具有隐式转换为双精度运算符的类时:
#include <cmath>
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 文档,上面写着(强调我的):
如果任何参数具有整数类型,则将其强制转换为 double。如果任何其他参数为 long double ,则返回类型为 long double ,否则为 double。
然而,Visual Studio 头文件中的实现似乎实现了“否则它是一个浮点数”。
任何人都知道意图是什么:-)?
通过在线 c++11 版本的 GCC 运行该示例(否则我无法简单访问 GCC 的最新副本),它似乎调用了 fmod 的“双”版本,这是我天真地期望的.
为了清楚起见,我正在使用
Microsoft (R) C/C++ 优化编译器版本 17.00.51106.1 for x86
这是附带的
Microsoft Visual Studio Express 2012 for Windows 桌面版 11.0.51106.01 更新 1