meryngii.neta

今日も新たな"ネタ"を求めて。

rel_ops

C++では==と!=のように片方だけあれば十分なものもすべて定義しなければならない。これを自動的に生成してくれるのがBoost.Operatorsなわけだが、標準ライブラリにもstd::rel_opsに比較演算のみ自動的に生成するものがあるようだ。

namespace rel_ops {
template <class T> bool operator != (const T& x, const T& y) {
	return !(x==y);
}
template <class T> bool operator >  (const T& x, const T& y) {
	return y<x;
}
template <class T> bool operator <= (const T& x, const T& y) {
	return !(y<x);
}
template <class T> bool operator >= (const T& x, const T& y) {
	return !(x<y);
}
}

かなりマイナーなようで、日本語の解説はあんまり無い。
http://www.s34.co.jp/cpptechdoc/reference/stl_samples/utility.html
おそらく問題なのは、using namespace std::rel_ops;としてしまうと、テンプレートで定義されているために比較演算できないものにまで及んでしまうことだろう。
ここで、C++0xのConceptが登場する。

By adding concept constraints to the operators in rel_ops, we eliminate nearly all of the problems with rel_ops that caused them to be banished. We could consider bringing them back into namespace std, if they are deemed useful.

rel_opsにあるoperatorsにconceptの制約を加えることで、rel_opsに関する問題はほとんど全て無くせる。もし役に立つようなら、namespace stdに戻すことも考えうる。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2735.pdf
#include <iostream>
#include <concepts>
#include <utility>

using namespace std::rel_ops;

class x
{
public:
	x(int val) : val_(val) { }
	
private:
	int val_;
	
	friend bool operator == (const x& a, const x& b)
	{
		return a.val_ == b.val_;
	}
};

int main()
{
	if (x(123) != x(234)) // OK
		std::cout << "test";
}

さらに+とかにも適用できればいいですね。