Sim*_*ons 7 c++ virtual-functions enable-if object-slicing c++11
我正在尝试使用它std::enable_if来专门化一个类,如果它的一个子类具有定义的特定成员函数.否则,它应该使用在基类中定义的默认实现.
#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;
}
Run Code Online (Sandbox Code Playgroud)
我原以为要印刷
Called Derived Method
1
Called Derived Method
1
Run Code Online (Sandbox Code Playgroud)
但是相反,我得到了
Called Base Method
0
Called Derived Method
1
Run Code Online (Sandbox Code Playgroud)
所以它看起来像正在发生一些物体切片.我不能为我的生活看到为什么会这样,如果有人能帮助我,将不胜感激.
如果它以任何方式帮助这是用g ++ 4.7.2编译的
模板功能不能是虚拟的.这也意味着模板函数永远不会覆盖基类中的虚函数,即使它的特定实例化签名恰好匹配.
要实现您的目标,您需要专注A于整体,在一个版本中提供成员而在另一个版本中不提供.
@Sebastian 的答案解释了这个问题,但建议的解决方案将会有问题:您无法使用 CRTP 在派生类的属性上专门化基类模板,因为在实例化基类时派生类不完整。我建议您始终重写f1in A,并使用标记分派来确定是分派到f2派生类还是默认实现Base:
template<typename Derived>
class A : public Base
{
double f1_impl(boost::mpl::true_, double x, double) const
{
std::cout << "Called Derived Method\n";
return static_cast<const Derived*>(this)->f2(x);
}
double f1_impl(boost::mpl::false_, double x, double y) const
{
return Base::f1(x, y);
}
public:
double f1(double x, double y) const override
{
using has_f2 = typename has_member_function_f2
< Derived
, double
, boost::mpl::list<double>
, boost::function_types::const_qualified
>::type;
return f1_impl(has_f2{}, x, y);
}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
267 次 |
| 最近记录: |