# std::is_pointer_interconvertible_with_class

< cpp‎ | types

定义于头文件 `<type_traits>` |  |
template<class S, class M> constexpr bool is_pointer_interconvertible_with_class( M S::* mp ) noexcept; |  | (C++20 起)

给定 `S` 类型对象 `s` ，确定是否 s.*mp 指代 `s` 的子对象且 `s` 与其子对象 s.*mp 指针可互转换。若 `S` 不是完整类型则程序为谬构。

若 `S` 不是标准布局类型 (StandardLayoutType) ，或 `M` 不是对象类型，或 `mp` 等于 nullptr ，则结果始终为 false 。

### 参数

mp | - | 要检测的成员指针

### 返回值

若 s.*mp 指代 `s` 的子对象且 `s` 与其子对象 s.*mp 指针可互转换则为 true ，否则为 false ，其中 `s` 是 `S` 类型对象。

### 注解

成员指针表达式 &S::m 的类型并非始终是 M S::* ，其中 `m` 的类型为 `M` ，因为 `m` 可能是从 `S` 的基类继承的成员。能指定第一模板实参以避免潜在地令人诧异的结果。

若存在 M S::* 类型值 `mp` 使得 std::is_pointer_interconvertible_with_class(mp) == true ，则 reinterpret_cast<M&>(s) 拥有良定义结果且与 s.*mp 指代同一子对象，其中 `s` 是合法的 `S` 类型左值。

在常用平台上，若 std::is_pointer_interconvertible_with_class(mp) == true ，则 `mp` 的位模式为全零。

### 示例

    #include <type_traits>
    #include <iostream>

    struct Foo { int x; };
    struct Bar { int y; };

    struct Baz : Foo, Bar {}; // 非标准布局

    int main()
    {
        std::cout << std::boolalpha
            << std::is_same_v<decltype(&Baz::x), int Baz::*>
            << std::is_pointer_interconvertible_with_class(&Baz::x) << '\n'
            << std::is_pointer_interconvertible_with_class<Baz>(&Baz::x) << '\n';
    }

输出：

    false
    true
    false

### 参阅

is_standard_layout (C++11) | 检查是否是一个标准布局类型 (类模板)
is_member_object_pointer (C++11) | 检查类型是否为指向非静态成员对象的指针 (类模板)