# std::is_corresponding_member

< cpp‎ | types

定义于头文件 `<type_traits>` |  |
template<class S1, class S2, class M1, class M2> constexpr bool is_corresponding_member( M1 S1::* mp, M2 S2::* mq ) noexcept; |  | (C++20 起)

确定 `mp` 与 `mq` 是否指代 `S1` 与 `S2` 的公共起始序列中的对应成员。若 `S1` 或 `S2` 为不完整类型则程序为谬构。

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

### 参数

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

### 返回值

若 `mp` 与 `mq` 指代 `S1` 与 `S2` 的公共起始序列中的对应成员则为 true ，否则为 false 。

### 注解

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

### 示例

    #include <type_traits>
    #include <iostream>

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

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

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

输出：

    true
    true
    true
    true
    false

### 参阅

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