If my base class has a function func(int)
and my derived class has a function func(double)
, the derived func(double)
hides base::func(int)
. I can use using
to bring the base version into the derive's list of overloads:
struct base
{
void func(int);
};
struct derived : base
{
using base::func;
void func(double);
}
OK, great. But what if I'm not sure whether base
has a func()
or not? ie because I am doing template metaprogramming, I'm not actually sure what base
is, but I want to bring its functions up to the same level - if they exist. ie change the above example to:
struct base_with
{
void func(int);
};
struct base_without
{
};
template <typename Base>
struct derived : Base
{
using Base::func; // if Base has a func(), I want to bring it in
void func(double);
}
derived<base_with> testwith; // compiles
derived<base_without> testwithout; // fails :-(
I need using_if
like boost::enable_if
. Doesn't seem possible...
Thanks in advance.
Since you're willing to put using
statements into your derived class, I assume you know beforehands which members you may be interested to bring in. You can do this using boost::enable_if
:
struct base_with
{
void func(int) { cout << "func(int)" << endl; }
};
struct base_without { };
// Custom traits, by default assume func() isn't present
template <class T> struct has_func : public boost::false_type { };
template<> struct has_func<base_with> : public boost::true_type { };
// Again, if nothing else is known, assume absence of func(int)
template <typename Base, class UseFunc = void> struct derived : Base
{
derived() { cout << "ctor: derived without" << endl; }
void func(double) { cout << "func(double)" << endl; }
};
// Derived with func(int)
template <typename Base> struct derived<Base, typename boost::enable_if< has_func<Base> >::type> : Base
{
using Base::func;
derived() { cout << "ctor: derived with" << endl; }
void func(double) { cout << "func(double)" << endl; }
};
Sorry for all the printing statements. Now if you try
derived<base_with> testwith;
derived<base_without> testwithout;
testwith.func(10);
testwith.func(10.5);
testwithout.func(10);
testwithout.func(10.5);
you should see
ctor: derived with
ctor: derived without
func(int)
func(double)
func(double)
func(double)
Obviously, this is going to get monstrous if you try to test for several features. If I was doing such mixin-style programming, I'd probably rather use functions with different names for different features so they wouldn't hide each other - then public inheritance would be all that is needed. Interesting question in any case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With