tmp/tmpah9oqnfk/{from.md → to.md}
RENAMED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
### Member relationships <a id="meta.member">[[meta.member]]</a>
|
| 2 |
+
|
| 3 |
+
``` cpp
|
| 4 |
+
template<class S, class M>
|
| 5 |
+
constexpr bool is_pointer_interconvertible_with_class(M S::*m) noexcept;
|
| 6 |
+
```
|
| 7 |
+
|
| 8 |
+
*Mandates:* `S` is a complete type.
|
| 9 |
+
|
| 10 |
+
*Returns:* `true` if and only if `S` is a standard-layout type, `M` is
|
| 11 |
+
an object type, `m` is not null, and each object `s` of type `S` is
|
| 12 |
+
pointer-interconvertible [[basic.compound]] with its subobject `s.*m`.
|
| 13 |
+
|
| 14 |
+
``` cpp
|
| 15 |
+
template<class S1, class S2, class M1, class M2>
|
| 16 |
+
constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept;
|
| 17 |
+
```
|
| 18 |
+
|
| 19 |
+
*Mandates:* `S1` and `S2` are complete types.
|
| 20 |
+
|
| 21 |
+
*Returns:* `true` if and only if `S1` and `S2` are standard-layout
|
| 22 |
+
types, `M1` and `M2` are object types, `m1` and `m2` are not null, and
|
| 23 |
+
`m1` and `m2` point to corresponding members of the common initial
|
| 24 |
+
sequence [[class.mem]] of `S1` and `S2`.
|
| 25 |
+
|
| 26 |
+
[*Note 1*:
|
| 27 |
+
|
| 28 |
+
The type of a pointer-to-member expression `&C::b` is not always a
|
| 29 |
+
pointer to member of `C`, leading to potentially surprising results when
|
| 30 |
+
using these functions in conjunction with inheritance.
|
| 31 |
+
|
| 32 |
+
[*Example 1*:
|
| 33 |
+
|
| 34 |
+
``` cpp
|
| 35 |
+
struct A { int a; }; // a standard-layout class
|
| 36 |
+
struct B { int b; }; // a standard-layout class
|
| 37 |
+
struct C: public A, public B { }; // not a standard-layout class
|
| 38 |
+
|
| 39 |
+
static_assert( is_pointer_interconvertible_with_class( &C::b ) );
|
| 40 |
+
// Succeeds because, despite its appearance, &C::b has type
|
| 41 |
+
// ``pointer to member of B of type int''.
|
| 42 |
+
static_assert( is_pointer_interconvertible_with_class<C>( &C::b ) );
|
| 43 |
+
// Forces the use of class C, and fails.
|
| 44 |
+
|
| 45 |
+
static_assert( is_corresponding_member( &C::a, &C::b ) );
|
| 46 |
+
// Succeeds because, despite its appearance, &C::a and &C::b have types
|
| 47 |
+
// ``pointer to member of A of type int'' and
|
| 48 |
+
// ``pointer to member of B of type int'', respectively.
|
| 49 |
+
static_assert( is_corresponding_member<C, C>( &C::a, &C::b ) );
|
| 50 |
+
// Forces the use of class C, and fails.
|
| 51 |
+
```
|
| 52 |
+
|
| 53 |
+
— *end example*]
|
| 54 |
+
|
| 55 |
+
— *end note*]
|
| 56 |
+
|