gpt4 book ai didi

c++ - 检测特定 C++ 类型是否有成员,排除继承的成员

转载 作者:行者123 更新时间:2023-12-02 15:53:01 25 4
gpt4 key购买 nike

我想检测特定类型是否有成员:直接检测,不是继承的结果

目的是确定特定类型是否“具有特征”,例如序列化的能力。当然,为了扩展示例,即使父类型具有序列化能力,子类型也可能不具备序列化能力。

  • 是否有(如果有的话)针对此请求的“标准”解决方案?
  • 底部介绍的不可转换指针方法是否存在缺陷(不包括其施加的限制)?

当使用 is_member_function_pointer 或其他检测机制时,继承就会发挥作用。请注意,即使 B 没有定义成员,输出也是“1”。

#include <type_traits>
#include <iostream>

struct A {
void member() { }
};

struct B : A {
};

int main()
{
std::cout << "B has member? "
<< std::is_member_function_pointer<decltype(&B::member)>::value
<< std::endl;
}

我能够实现的最接近的是使用不可转换指针时(B** 没有隐式转换为 A**),尽管这是合作起来有点尴尬。它还强加与类型匹配的附加参数并防止任何直接继承。

#include <type_traits>
#include <iostream>

struct A {
// would match std::declval<B*> as B* -> A*,
// hence forcing failure through B** -> A**.
// void member(A*) { }
void member(A**) { }
};

struct B : A {
// succeeds compilation aka "found" if not commented
// void member(B**) { }
};

int main()
{
// This actually fails to compile, which is OKAY because it
// WORKS when used with SFINAE during the actual detection.
// This is just a simple example to run.
// error: invalid conversion from 'B**' to 'A**'
std::cout << "B has member? "
<< std::is_member_function_pointer<
decltype(std::declval<B>().member(std::declval<B**>()))
>::value
<< std::endl;
}

最佳答案

有一个巧妙的技巧可以帮助解决这个问题。

&B::member的类型实际上是void (A::*)(),而不是void (B::*)() (如果 member 是继承的)。

使用 SFINAE 检查 &B::member 是否存在并且具有正确的类型:

template <typename T, typename = void>
struct has_member : std::false_type {};

template <typename T> struct has_member
<T, std::enable_if_t<std::is_same_v<void (T::*)(), decltype(&T::member)>>>
: std::true_type
{};

这仅适用于一种特定的成员类型(member 必须是 void member())。将其推广到任何类型将作为读者的练习。

<小时/>

或者您可以花哨并使用这样一个事实:void (B::*)() 由于某种原因不能隐式转换为 void (A::*)() 特别是在传递模板参数时:

template <typename T, T>
struct detect_member_helper {};

template <typename T>
using detect_member = detect_member_helper<void (T::*)(), &T::member>;

template <typename T>
inline constexpr bool has_member = std::experimental::is_detected_v<detect_member, T>;

关于c++ - 检测特定 C++ 类型是否有成员,排除继承的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60178516/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com