检查成员函数是否存在,并且不继承SFINAE [英] Check if member function exists and is not inherited for 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());
}
所需输出: / 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);
}
};
这篇关于检查成员函数是否存在,并且不继承SFINAE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!