How can I check if a member function exists and is not inherited?
I need this to resolve ambiguity for the following example:
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.
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());
}
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.
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-inheritedbar
.live example
With a bunch of template, we can get it as it follows:
Adjust the
call
methods according with your requirements.I've set a few defaults I'm not sure are fine.