类型特性
类型特性定义一个编译时基于模板的结构,以查询或修改类型的属性。
试图特化定义于 <type_traits> 头文件的模板导致未定义行为,除了 std::common_type 可依照其所描述特化。
定义于<type_traits>头文件的模板可以用不完整类型实例化,除非另外有指定,尽管通常禁止以不完整类型实例化标准库模板。
受支持操作
检查二个指定成员是否在二个指定类型中的公共起始序列中彼此对应
std::is_corresponding_member
template< class S1, class S2, class M1, class M2 > | (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 <iostream>
#include <type_traits>
#include <typeinfo>
namespace std
{
template <typename Type1, typename Type2, typename MemberType1, typename MemberType2>
struct is_corresponding_member
{
static const bool value = std::is_same<MemberType1, MemberType2>::value;
};
template<typename Type1, typename Type2, typename MemberType1, typename MemberType2>
const bool is_corresponding_member_v =
is_corresponding_member<Type1, Type2, MemberType1, MemberType2>::value;
}
class MyClass
{
public:
int x;
double y;
};
class A {};
class B : public A {};
class C {};
class D
{
public:
operator C()
{
return c;
} C c;
};
class F
{
};
class S final
{
};
int main()
{
std::cout << std::boolalpha;
int MyClass::* ptr1 = &MyClass::x;
double MyClass::* ptr2 = &MyClass::y;
int MyClass::* ptr3 = &MyClass::x;
std::cout << "typeid(ptr1).name(): " << typeid(ptr1).name() << std::endl;
std::cout << "typeid(ptr2).name(): " << typeid(ptr2).name() << std::endl;
std::cout << "typeid(ptr3).name(): " << typeid(ptr3).name() << std::endl;
std::cout << "std::is_corresponding_member<MyClass, MyClass, decltype(ptr1), decltype(ptr2)>::value: "
<< std::is_corresponding_member<MyClass, MyClass, decltype(ptr1), decltype(ptr2)>::value << std::endl;
std::cout << "std::is_corresponding_member<MyClass, MyClass, decltype(ptr1), decltype(ptr3)>::value: "
<< std::is_corresponding_member<MyClass, MyClass, decltype(ptr1), decltype(ptr3)>::value << std::endl;
C c;
D d;
std::cout << "typeid(c).name(): " << typeid(c).name() << std::endl;
std::cout << "typeid(d).name(): " << typeid(d).name() << std::endl;
std::cout << "std::is_corresponding_member<MyClass, MyClass, decltype(ptr1), decltype(ptr3)>::value: "
<< std::is_corresponding_member<D, C, decltype(c), decltype(d)>::value << std::endl;
return 0;
}
输出
typeid(ptr1).name(): M7MyClassi
typeid(ptr2).name(): M7MyClassd
typeid(ptr3).name(): M7MyClassi
std::is_corresponding_member<MyClass, MyClass, decltype(ptr1), decltype(ptr2)>::value: false
std::is_corresponding_member<MyClass, MyClass, decltype(ptr1), decltype(ptr3)>::value: true
typeid(c).name(): 1C
typeid(d).name(): 1D
std::is_corresponding_member<MyClass, MyClass, decltype(ptr1), decltype(ptr3)>::value: false