これは今日仕事で出てきたので、私はそれをコミュニティに捨てようと思いました。
同僚が次のコードを書きました(多かれ少なかれ):
#include <algorithm>
double chop(double x) {
return std::max(0, x);
}
std::max
ただし、両方の引数がまったく同じ型である必要があるため、これはコンパイルすらしません。これは、参照のペアを取得して参照を返すことができるようにするためだと思います。これは、ユーザー定義型で呼び出す場合に必要になる可能性が非常に高くなります。けっこうだ。
もちろん、修正はを使用することstd::max(0.0, x)
です。
私が嘘をついたので、今しばらく私と一緒に耐えてください。私の同僚が実際に書いたのはこれでした:
// Included from a very old header file written by someone long gone
template<class T1, class T2>
inline T1 myMax(T1 x, T2 y) {
return (x < y) ? y : x;
}
double chop(double x) {
return myMax(0, x);
}
これでコンパイルされます!しかし、たとえば0.25に等しいxに対しては、かなり驚くべき結果が得られます。彼が問題を見つけるのにどれくらいの時間がかかったかはわかりません。問題を見つけた後でも、なぜそれが機能しなかったのかを尋ねなければなりませんでした。
私の答えは、(a)0の代わりに0.0を使用する(バグを修正する)、および(b)std::max
の代わりに使用するmyMax
(あなたがそれについて考えるとき、その振る舞いは非常に恐ろしい)でした。
しかし、彼はなぜそれが必要なのか疑問に思っています。0 + x
つまり、彼はまたは0 * x
またはを書くことができる0 - x
ので、なぜmyMax(0, x)
ですか?
これが彼が望むものを彼に与える最初のパスです:
// this is from the .hh file
// template meta-program to compute the "wider" of two types given as argument
template<class T1, class T2>
struct WiderType {
};
// Partial specialization for case where both types are same
template<class T>
struct WiderType<T, T> {
typedef T type;
};
// Specialization for first type "int" and second type "double"
template<>
struct WiderType<int, double> {
typedef double type;
};
template<class T1, class T2>
inline typename WiderType<T1,T2>::type
myMax(T1 a, T2 b) {
return ((a < b) ? b : a);
}
// this is from the .cc file
double chop(double x) {
return myMax(0, x);
}
// just to show this still works
int chop(int x) {
return myMax(0, x);
}
WiderType
これで、整数型のすべてのペアに加えて、他の通常の算術変換を行うための特殊化を実行して追加することができました。(そして私はそれUsualConversions
か何かの名前を変更できると思います。)
しかし、もっと簡単な方法はありますか?つまり、C ++言語を使用すると、さまざまな組み込みの算術演算子と同じ変換を引数に対して実行する独自の関数を簡単に定義できますか?