新しいC++11ヘッダーを使用したVisualC++ 2012での動作が、VC ++2010での使用とは異なるサンプルコードがいくつかあります。これは、cmathをインクルードしたときに取得するstd::fmod関数を呼び出すとどうなるかに関するものです。渡す引数がdoubleではなく、double演算子への暗黙の変換を持つクラスである場合:
#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;
}
驚いたことに、これは2つのdoubleをとるfmodのバージョンではなく、2つのfloatをとるfmodのバージョンを呼び出します。
だから私の質問は、これはC ++ 11標準を与えられた正しい振る舞いですか?動作について私が見つけることができる唯一の情報は、ここのcppreference.comドキュメントにあります。
いずれかの引数が整数型の場合、doubleにキャストされます。他の引数がlongdoubleの場合、戻り型はlong doubleになり、それ以外の場合はdoubleになります。
ただし、Visual Studioヘッダーファイルでの実装は、「それ以外の場合はフロート」を実装しているように見えます。
誰もが意図が何であるかを知っています:-)?
GCCのオンラインc++11バージョンで例を実行すると(GCCの最近のコピーに簡単にアクセスすることはできません)、fmodの「ダブル」バージョンを呼び出しているように見えます。これは私が素朴に期待していることです。 。
明確にするために、私は使用しています
Microsoft(R)C /C++最適化コンパイラバージョン17.00.51106.1forx86
付属しているものです
Microsoft Visual Studio Express 2012 forWindowsDesktopバージョン11.0.51106.01Update1