最近になってBoost::fc++というのを知りました。C++を関数型言語風に使おうというライブラリなのですが、その中に次のような記述があるのを見つけました。
x %plus% y
おぉ、演算子を自作している!
この発想はなかったので、ちょっと衝撃でした。
この式を普通の関数呼び出しの形式に展開すると、
operator % (x, plus).operator % (y)
となるわけで、%演算子のオーバーロードがキモになっているようです。
そんな訳で、これをまねて、自作の演算子を実装してみました。
// 演算子の基底クラス struct Op { virtual ~Op() {} virtual int eval(int lhs, int rhs) const = 0; }; // 演算する値と演算子を演算まで中継するクラス class Result { public: Result(int lhs, const Op& op) : lhs_(lhs), op_(op) {} int operator % (int rhs) { return op_.eval(lhs_, rhs); } private: int lhs_; const Op& op_; }; // 最初の%(左側の値と演算子をバインドする) Result operator % (int lhs, const Op& op) { return Result(lhs, op); } // ここから使用例 struct Plus : public Op { int eval(int lhs, int rhs) const { return lhs + rhs; } }; struct Minus : public Op { int eval(int lhs, int rhs) const { return lhs - rhs; } }; struct Times : public Op { int eval(int lhs, int rhs) const { return lhs * rhs; } }; const Plus plus; const Minus minus; const Times times; #include <iostream> int main(int, char* []) { int x = 12; int y = 34; std::cout << (x %plus% y) << std::endl; std::cout << (x %minus% y) << std::endl; std::cout << (x %times% y) << std::endl; return 0; }
Result::operator %
の中で演算結果を返してますが、代わりに関数オブジェクトなどを返すことで遅延演算もできるはずです。