项目地址:http://code.google.com/p/febird
/** @brief 生成一个比较器(Comparator),兼键提取(KeyExtractor)类 使用这个宏生成的比较器可以作用在不同的对象上,只要这些对象有相同名称的成员, 并且可以作用在类型为成员类型的对象上。 - 假设: - 有 n 个类 class[1], class[2], ... class[n],都有类型为 MemberType ,名称为 MemberName 的数据成员 - 那么以下类型的对象可以使用该类相互比较,并且可以从这些对象中提取出 MemberType 类型的键: class[1] ... class[n], MemberType, 以及所有这些类型的任意级别的指针 @param ComparatorName 比较器类的名字 @param MemberType 要比较的对象的成员类型 @param MemberName 要比较的对象的成员名字,也可以是一个成员函数调用, 前面必须加 '.' 或者 '->', 加 '->' 只是为用于 smart_ptr/iterator/proxy 等重载 '->' 的对象 当用于裸指针时,仍使用 '.',这意味着裸指针和 smart_ptr/iterator/proxy 不能使用同一个生成的 Comparator,虽然裸指针的语法和它们都相同 @param ComparePred 比较准则,这个比较准则将被应用到 XXXX MemberName @note - 这个类不是从 ComparePred 继承,为的是可以允许 ComparePred 是个函数, 但这样(不继承)阻止了编译器进行空类优化 - 不在内部使用 const MemberType&, 而是直接使用 MemberType, 是为了允许 MemberName 是一个函数时,返回一个即时计算出来的 Key; - 当为了效率需要使用引用时,将 const MemberType& 作为 MemberType 传进来 - 当 MemberType 是个指针时,将 Type* 作为 MemberType ,而非 const Type*,即使 MemberType 真的是 const Type* - 注意 C++ 参数推导机制: @code template<T> void f(const T& x) { } // f1 template<T> void f(const T* x) { } // f2 template<T> void g(const T& x) { } // g1 template<T> void g(const T* x) { } // g2 template<T> void g( T& x) { } // g3 template<T> void g( T* x) { } // g4 void foo() { int a; const int b; f(&a); // call f1, T was deduced as int*, and then convert to 'const int*&', so match f1, not f2 f(&b); // call f2, T was deduced as int g(&a); // call g4, T was deduced as int g(&b); // call g2, T was deduced as int } @endcode 在上述代码已经表现得比较明白了,这就是要生成四个不同 deref 版本的原因 - 为了配合上述机制,传入的 MemberType 不要有任何 const 修饰符 */ #define SAME_NAME_MEMBER_COMPARATOR_EX(ComparatorName, MemberType, MemberName, ComparePred) \ class ComparatorName \ { \ ComparePred m_comp; \ public: \ typedef bool result_type; \ typedef MemberType key_type; \ typedef boost::integral_constant<bool, \ febird::HasTriCompare<ComparePred>::value \ > has_tri_compare; \ \ ComparatorName() {} \ ComparatorName(const ComparePred& rhs) \ : m_comp(rhs) {} \ \ template<class T>const T&deref(T*x)const{return*x;} \ template<class T>const T&deref(T&x)const{return x;} \ template<class T>const T&deref(const T*x)const{return*x;}\ template<class T>const T&deref(const T&x)const{return x;}\ \ const MemberType operator()(const MemberType x)const{return x;} \ template<class T>const MemberType operator()(const T&x)const{return deref(x)MemberName;}\ \ template<class Tx, class Ty> \ bool operator()(const Tx&x, const Ty&y) const \ { \ return m_comp((*this)(x),(*this)(y)); \ } \ template<class Tx, class Ty> \ int compare(const Tx&x, const Ty&y) const \ { \ return m_comp.compare((*this)(x),(*this)(y)); \ } \ }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #endif // #define SAME_NAME_MEMBER_COMPARATOR_EX(ComparatorName, MemberType, MemberName, ComparePred) \ // SAME_NAME_MEMBER_COMPARATOR_EX_NO_TRAITS(ComparatorName, MemberType, MemberName, ComparePred)\ // BOOST_TT_AUX_BOOL_TRAIT_SPEC1(HasTriCompare, ComparatorName, HasTriCompare<ComparePred>::value) //! note@ if MemberType must not be a reference, neither const nor non-const #define SAME_NAME_MEMBER_COMPARATOR(ComparatorName, MemberType, MemberName) \ SAME_NAME_MEMBER_COMPARATOR_EX(ComparatorName, MemberType, MemberName, std::less<MemberType>)
项目地址:http://code.google.com/p/febird