62 lines
2.8 KiB
Markdown
62 lines
2.8 KiB
Markdown
[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<class S, class M>
|
||
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<class S1, class S2, class M1, class M2>
|
||
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>( &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*]
|
||
|
||
â *end note*]
|