检查类是否有一个函数中有参数 [英] Checking if a class has a function that has parameters in it

查看:144
本文介绍了检查类是否有一个函数中有参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读了可以写一个C ++模板来检查函数的存在吗?,并且测试了几个答案,我发现它只适用于没有参数的检测函数,EG void HelloWord ()。

Having read the question from Is it possible to write a C++ template to check for a function's existence?, and tested a few of the answers, I find it only works on detecting functions that take no parameters, EG void HelloWord(). Searching around for answers either just gives solutions to parameterless functions or eye-wateringly complex solutions that I can't make head nor tail of.

这里是我的宏模板代码,用于构造一个非常复杂的解决方案。检测器:

Here's my macro template code for constructing detectors:

#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)?

How do I modify the above code in order to detect a member function in a class, that contains parameters, EG void SetPosition(float,float)?

我愿意接受是总重写的解决方案,但如果任何解决方案比上述更复杂,以解释发生在尽可能多的深度,所以我(和大概是其他人)可以理解它是如何工作的。对我来说,我不知道你写的是什么意思。

I'm willing to accept solutions that are total rewrites, but if any solutions are more complex than the above, please try to explain what is happening in as much depth as possible so I (and presumably others) can understand how it works. Treat me like I have no idea what anything of what you wrote means.

推荐答案

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

Since you want to check both, whether there's a member function of a specific signature, and also, whether a given function is callable with some arguments type, you could utilize the detection idiom for that:

#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...>;

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

Now you just need to add some custom detectors:

// 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 ,而第一个trait拒绝此类,第二个评估为true。

Note the difference with class B, while the first trait rejects this class, the second one evaluates to true.

DEMO

这篇关于检查类是否有一个函数中有参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆