Returns: true if and only if
S is a standard-layout type,
M is an object type,
m is not null,
and each object s of type S
is pointer-interconvertible ([basic.compound])
with its subobject s.*m.
Returns: true if and only if
S1 and S2 are standard-layout types,
M1 and M2 are object types,
m1 and m2 are not null,
and m1 and m2 point to corresponding members of
the common initial sequence ([class.mem]) of S1 and S2.
The type of a pointer-to-member expression &C::b
is not always a pointer to member of C,
leading to potentially surprising results
when using these functions in conjunction with inheritance.
[Example 1: struct A {int a; }; // a standard-layout classstruct B {int b; }; // a standard-layout classstruct C:public A, public B {}; // not a standard-layout classstatic_assert( is_pointer_interconvertible_with_class(&C::b ));
// Succeeds because, despite its appearance, &C::b has type// “pointer to member of B of type int”.static_assert( is_pointer_interconvertible_with_class<C>(&C::b ));
// Forces the use of class C, and fails.static_assert( is_corresponding_member(&C::a, &C::b ));
// Succeeds because, despite its appearance, &C::a and &C::b have types// “pointer to member of A of type int” and// “pointer to member of B of type int”, respectively.static_assert( is_corresponding_member<C, C>(&C::a, &C::b ));
// Forces the use of class C, and fails. — end example]