检查成员函数是否存在,并且不继承SFINAE [英] Check if member function exists and is not inherited for SFINAE

查看:158
本文介绍了检查成员函数是否存在,并且不继承SFINAE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何检查成员函数是否存在并继承?

How can I check if a member function exists and is not inherited?

我需要此函数来解决以下示例的歧义:

I need this to resolve ambiguity for the following example:

一种类型有 foo() bar c $ c>成员函数。 Caller 调用为给定类型存在的。但是, DerivedWithBar 继承 foo() BaseWithFoo 它自己的 bar()。因此, Caller 不知道要调用哪个函数。

A type either has a foo() or a bar() member function. Caller will call the one that exists for the given type. However, DerivedWithBar inherits foo() from BaseWithFoo but defines its own bar(). Thus, Caller does not know which function to call.

我需要一种方法,继承 foo 优先于继承的 bar(),但我不知道如何检查成员函数是否继承

I'd need a way to give the non-inherited foo precedence over the inherited bar(), but I do not know how to check if a member function is inherited or not.

#include <iostream>

struct BaseWithFoo
{
    template <typename T> void foo(T&&){std::cout << "Base::foo" << std::endl;}
};

struct DerivedWithBar : public BaseWithFoo
{
    template <typename T> void bar(T&&){std::cout << "DerivedWithBar::bar" << std::endl;}
};

struct DerivedWithFoo : public BaseWithFoo
{
    template <typename T> void foo(T&&){std::cout << "DerivedWithFoo::foo" << std::endl;}
};

struct EmptyDerived : public BaseWithFoo {};

struct BaseWithBar
{
    template <typename T> void bar(T&&){std::cout << "BaseWithBar::bar" << std::endl;}
};


struct Caller
{
    template <typename T>
    auto call(T&& x) -> decltype(x.foo(*this), void())
    {
        x.foo(*this);
    }

    template <typename T>
    auto call(T&& x) -> decltype(x.bar(*this), void())
    {
        x.bar(*this);
    }
};

int main()
{
  Caller c;
  c.call(BaseWithFoo());
  c.call(DerivedWithFoo());
  c.call(DerivedWithBar());
  c.call(EmptyDerived());
  c.call(BaseWithBar());
}

live example

所需输出: / p>

desired output:

Base::foo
DerivedWithFoo::foo
DerivedWithBar::bar
Base::foo
BaseWithBar::bar


推荐答案

通过比较成员函数指针的类型来区分继承成员函数和非继承成员函数的方法。

I found a way to distinguish between inherited and non-inherited member functions by comparing types of member function pointers.

以下是我完全问题的部分解决方案(继承成员函数优先于继承成员函数)。这将只调用非继承的 foo 或非继承的 bar

The following is a partial solution to my full problem ("giving non-inherited member functions precedence over inherited ones"). This will only call non-inherited foo or non-inherited bar.

struct Caller
{    
    template <typename T>
    auto call(T&& x) -> decltype(x.foo(*this),
        std::enable_if_t<
            std::is_same<
                decltype(&T::template foo<decltype(*this)>),
                void (T::*)(decltype(*this))
            >::value
        >())
    {
        x.foo(*this);
    }

    template <typename T>
    auto call(T&& x) -> decltype(x.bar(*this),
        std::enable_if_t<
            std::is_same<
                decltype(&T::template bar<decltype(*this)>),
                void (T::*)(decltype(*this))
            >::value
        >())
    {
        x.bar(*this);
    }
};

live example

这篇关于检查成员函数是否存在,并且不继承SFINAE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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