gpt4 book ai didi

c++ - 检查一个类是否具有给定签名的成员函数

转载 作者:IT老高 更新时间:2023-10-28 11:34:42 25 4
gpt4 key购买 nike

我要求一个模板技巧来检测一个类是否具有给定签名的特定成员函数。

问题与此处引用的问题类似 http://www.gotw.ca/gotw/071.htm但不一样:在 Sutter 的书中,他回答了类 C 必须提供具有特定签名的成员函数的问题,否则程序将无法编译。在我的问题中,如果一个类具有该功能,我需要做一些事情,否则做“其他事情”。

boost::serialization 也面临类似的问题,但我不喜欢他们采用的解决方案:一个模板函数默认调用具有特定签名的自由函数(您必须定义),除非您定义一个特定的具有特定签名的成员函数(在他们的情况下“序列化”,它采用给定类型的 2 个参数),否则会发生编译错误。那就是实现侵入式和非侵入式序列化。

我不喜欢那个解决方案有两个原因:

  1. 为了非侵入性,您必须覆盖 boost::serialization 命名空间中的全局“序列化”函数,因此您可以在您的客户端代码中打开命名空间提升和命名空间序列化!
  2. 解决该问题的堆栈困惑是 10 到 12 次函数调用。

我需要为没有该成员函数的类定义自定义行为,并且我的实体位于不同的命名空间中(并且我不想在一个命名空间中覆盖定义在另一个命名空间中的全局函数)

你能给我一个提示来解决这个难题吗?

最佳答案

这是一个依赖于 C++11 特性的可能实现。即使它是继承的,它也能正确检测到函数(与已接受答案中的解决方案不同,正如 Mike Kinghan 在 his answer 中观察到的那样)。

此代码段测试的函数称为 serialize:

#include <type_traits>

// Primary template with a static assertion
// for a meaningful error message
// if it ever gets instantiated.
// We could leave it undefined if we didn't care.

template<typename, typename T>
struct has_serialize {
static_assert(
std::integral_constant<T, false>::value,
"Second template parameter needs to be of function type.");
};

// specialization that does the checking

template<typename C, typename Ret, typename... Args>
struct has_serialize<C, Ret(Args...)> {
private:
template<typename T>
static constexpr auto check(T*)
-> typename
std::is_same<
decltype( std::declval<T>().serialize( std::declval<Args>()... ) ),
Ret // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>::type; // attempt to call it and see if the return type is correct

template<typename>
static constexpr std::false_type check(...);

typedef decltype(check<C>(0)) type;

public:
static constexpr bool value = type::value;
};

用法:

struct X {
int serialize(const std::string&) { return 42; }
};

struct Y : X {};

std::cout << has_serialize<Y, int(const std::string&)>::value; // will print 1

关于c++ - 检查一个类是否具有给定签名的成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/87372/

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