I attempted the following approach using c++ SFINAE and std::declval
to find if there exists the proper method in a base class, that can be called from the derived class. The derived class gets the base class from a template parameter. This works for a public method in the base class but not a protected method. Ideally I would prefer to keep the method I'm checking for protected. Here is the simplified code
template <class Base>
class Derived : public Base {
// SFINAE tester to find existence of foo (only works with public foo methods)
template <class Type>
static auto test_foo(int) -> decltype(std::declval<Type>().foo(std::declval<Bar&>()), std::true_ type());
template <class>
static auto test_foo(...) -> std::false_type;
using has_foo = decltype(test_foo<Base>(0));
// using the has_foo constexpr
void process_bar(Bar& bar) {
if constexpr (has_foo{})
Base::foo(bar);
...
}
};
Is there a way to transform this so that it can access the protected member of the base class while using declval (I think using std::declval<Base>
might be making it so that it doesn't have access to the protected members of Base
despite inheriting from it). Any help is appreciated, thanks!
So I ended up using Ted Lyngmo's comment for my personal problem, it requires using requires
from c++20, if you can't use c++20 maybe try using max66's answer. requires
is way less verbose than the decltype testing which although neat is a little ugly and less portable. Here's the code that works for me:
template <class Base>
class Derived : public Base {
// using requires constexpr
void process_bar(Bar& bar) {
if constexpr (requires{Base::foo(bar);})
Base::foo(bar);
...
}
};