I'm attempting to use std::enable_if
to specialise a class if one of it's subclasses has a specific member function defined. Otherwise it should use a default implementation that is defined in the base class.
#include <boost/mpl/list.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/tti/has_member_function.hpp>
#include <iostream>
#include <type_traits>
#include <memory>
BOOST_TTI_HAS_MEMBER_FUNCTION(f2)
class Base
{
public:
virtual double f1(double x, double y) const
{
std::cout << "Called Base Method" << std::endl;
return 0.0;
}
};
template<typename Derived>
class A : public Base
{
public:
template<typename T = Derived>
typename std::enable_if
< has_member_function_f2< T
, double
, boost::mpl::list<double>
, boost::function_types::const_qualified
>::value
, double
>::type
f1(double x, double y) const
{
std::cout << "Called Derived Method" << std::endl;
return static_cast<const Derived* const>(this)->f2(x);
}
};
class B : public A<B>
{
public:
double f2(double x) const
{
return 1.0;
}
};
int main()
{
std::unique_ptr<Base> base_instance( new B );
std::cout << base_instance->f1(100.0, 10.0) << std::endl;
B b_instance;
std::cout << b_instance.f1(100.0, 10.0) << std::endl;
return 0;
}
I would have expected this to print
Called Derived Method
1
Called Derived Method
1
however instead I get
Called Base Method
0
Called Derived Method
1
so it looks like some object slicing is occurring. I can't for the life of me see why this would be the case, if anyone could help me that would be greatly appreciated.
If it helps in any way this is being compiled with g++ 4.7.2
std::enable_if
but I assumed that the type of f1 in B would bedouble f1(double, double) const
and thus should be picked up as the virtual function. – Gerita