gpt4 book ai didi

c++ - 检查一个类是否有一个有参数的函数

转载 作者:行者123 更新时间:2023-11-30 03:42:01 27 4
gpt4 key购买 nike

阅读了来自 Is it possible to write a C++ template to check for a function's existence? 的问题,并测试了一些答案,我发现它只适用于检测不带参数的函数,EG void HelloWord()。四处寻找答案要么只是给出无参数函数的解决方案,要么是我无法弄清楚的令人眼花缭乱的复杂解决方案。

这是我构建检测器的宏模板代码:

#define MEMBERFUNCTIONTODETECT(CONTAINS_NAME,MEMBERFUNCTION) \
template <typename TemplateItem>\
class CONTAINS_NAME\
{\
typedef char Yes;\
typedef char No[2];\
\
template <typename TemplateClass> static Yes &Test( decltype(&TemplateClass::MEMBERFUNCTION) );\
template <typename TemplateClass> static No &Test(...);\
\
public:\
enum { Value = sizeof(Test<TemplateItem>(0)) == sizeof(char) };\
};

如何修改上述代码以检测类中包含参数 EG void SetPosition(float,float) 的成员函数?

我愿意接受完全重写的解决方案,但如果有任何解决方案比上述更复杂,请尝试尽可能深入地解释正在发生的事情,以便我(可能还有其他人)能够理解它是如何发生的作品。对待我,就好像我不知道你写的是什么意思。

最佳答案

既然你想检查两者,是否有一个特定签名的成员函数,以及一个给定的函数是否可以用某些参数类型调用,你可以使用 detection idiom为此:

#include <type_traits>
#include <utility>

template <typename...>
using void_t = void;

template <typename AlwaysVoid, template <typename...> class Operation, typename... Args>
struct detect_impl : std::false_type {};

template <template <typename...> class Operation, typename... Args>
struct detect_impl<void_t<Operation<Args...>>, Operation, Args...> : std::true_type {};

template <template <typename...> class Operation, typename... Args>
using detect = detect_impl<void_t<>, Operation, Args...>;

现在您只需要添加一些自定义检测器:

// Check specific signature
template <typename T, typename Sig>
using has_SetPosition = decltype(static_cast<Sig>(&T::SetPosition));

// Check if the function can be called with Args...
template <typename T, typename... Args>
using can_call_SetPosition = decltype(std::declval<T>().SetPosition(std::declval<Args>()...));

测试:

struct A
{
void SetPosition(float, float) {}
};

struct B
{
void SetPosition(int, int) {}
};

struct C
{
};

int main()
{
static_assert(detect<has_SetPosition, A, void(A::*)(float, float)>{}, "!");
static_assert(!detect<has_SetPosition, B, void(B::*)(float, float)>{}, "!");
static_assert(!detect<has_SetPosition, C, void(C::*)(float, float)>{}, "!");

static_assert(detect<can_call_SetPosition, A&, float, float>{}, "!");
static_assert(detect<can_call_SetPosition, B&, float, float>{}, "!");
static_assert(!detect<can_call_SetPosition, C&, float, float>{}, "!");
}

注意与 B 类的区别,第一个特征拒绝这个类,第二个特征评估为真。

DEMO

关于c++ - 检查一个类是否有一个有参数的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37054274/

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