[meta.member] # 21 Metaprogramming library [[meta]](./#meta) ## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.member) ### 21.3.11 Member relationships [meta.member] [🔗](#lib:is_pointer_interconvertible_with_class) `template constexpr bool is_pointer_interconvertible_with_class(M S::*m) noexcept; ` [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2744) *Mandates*: S is a complete type[.](#1.sentence-1) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2748) *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]](basic.compound "6.9.4 Compound types")) with its subobject s.*m[.](#2.sentence-1) [🔗](#lib:is_corresponding_member) `template constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept; ` [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2766) *Mandates*: S1 and S2 are complete types[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2770) *Returns*: true if and only if S1 and S2 are standard-layout struct ([[class.prop]](class.prop "11.2 Properties of classes")) 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]](class.mem "11.4 Class members")) of S1 and S2[.](#4.sentence-1) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2780) [*Note [1](#note-1)*: 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[.](#5.sentence-1) [*Example [1](#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::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::a, &C::b ) ); // Forces the use of class C, and fails. — *end example*] — *end note*]