ところで、昨日の記事で、以下のコードはコンパイルエラーになって面倒だという話をした。
template<typename T> T f(T x, T y) { return x + y; } auto z = f(1.0f, 2.0); // f(float, double)
一応追記しておくと、これはtemplate
だから生じる問題とかではなくて、オーバーロードでも普通に生じる。
double f(double x, double y) { return x + y; } float f(float x, float y) { return x + y; } auto z = f(1.0f, 2.0); // f(float, double)
もちろん、理由はambiguous
だからだ。
prog.cc: In function 'int main()': prog.cc:14:25: error: call of overloaded 'f(float, double)' is ambiguous auto z = f(1.0f, 2.0); ^ prog.cc:3:8: note: candidate: 'double f(double, double)' double f(double x, double y) ^ prog.cc:7:7: note: candidate: 'float f(float, float)' float f(float x, float y) ^
一般に、浮動小数点数のリテラル値を書くときは色々と面倒が生じるということになる。
一度明示的に定義した型で受けてしまえば、この手の問題は発生しない。
float x = 1.0 / w; float y = 2.0 * w; auto z = f(x, y);
冗長ではあるが。