我阅读了有关内置比较运算符的信息。我想知道为什么成员指针没有排序运算符(<
、、、、<=
)。比较结构实例化的两个成员的地址是有效的。>
>=
http://en.cppreference.com/w/cpp/language/operator_comparison:
3) 如果在一个非联合类类型的对象中,两个指针指向具有相同成员访问权限的不同非静态数据成员,或者指向这些成员的子对象或数组元素,递归地,指向后面声明的成员的指针进行比较更大。换句话说,三种成员访问模式中的每一种中的类成员都按声明顺序定位在内存中。
使用 adressof operator( &
) 和成员指针解引用 operator( .*
) 可以比较地址,但需要一个实例。
我的问题:
为什么没有用于成员指针的内置排序运算符?
如何在没有实例的情况下比较两个成员指针?
我的做法:
#include <iostream>
template<class S, class T>
int cmp_memberptr(T S::* a, T S::* b) {
//S s; // works, but needed instanciation
//S& s = std::declval<S>(); // error
S& s = *(S*)nullptr; // no instanciation, works (on my machine), but undefined behavior because of nullptr dereference (most compilers warn directly)!
// note: the precedence of .*:
return int(&(s.*a) < &(s.*b)) - int(&(s.*a) > &(s.*b));
};
struct Point { int x, y; };
int main(int argc, char const* const* argv) {
Point p;
#define tst(t) std::cout << #t " is " << ((t) ? "true" : "false") << '\n'
tst(&p.x < &p.y);
//tst(&Point::x < &Point::y); // the main problem!
tst(cmp_memberptr(&Point::x, &Point::y) < 0);
#undef tst
};
我考虑了offsetof
-macro,但它不将成员指针作为参数。