【发布时间】:2013-07-05 00:00:52
【问题描述】:
我正在尝试为学术目的制作一个自定义碰撞引擎,但我遇到了一个通用的 c++ 编程问题。我已经拥有所有可以正常工作的几何图形,并且碰撞测试也可以正常工作。
引擎使用这两个类来创建一个几何队列来测试:
class collidable;
template<typename geometry_type>
class collidable_object : public collidable;
由于可能有多种几何类型,我不想手动指定要测试的任何碰撞。
我使用这种“技术”来实现双重调度:
class collidable
{
public:
typedef bool (collidable::*collidable_hit_function)(const collidable& ) const;
virtual ~collidable() = 0 {}
virtual collidable_hit_function get_hit_function() const = 0;
};
template<typename geometry_type>
class collidable_object : public collidable
{
public:
explicit collidable_object( geometry_type& geometry ) :
m_geometry( geometry )
{}
~collidable_object(){}
virtual collidable_hit_function get_hit_function() const
{
return static_cast<collidable_hit_function>( &collidable_object<geometry_type>::hit_function<geometry_type> );
}
template<typename rhs_geometry_type>
bool hit_function( const collidable& rhs ) const
{
return check_object_collision<geometry_type, rhs_geometry_type>( *this, rhs );
}
const geometry_type& geometry() const
{
return m_geometry;
}
private:
geometry_type& m_geometry;
};
bool check_collision( const collidable& lhs, const collidable& rhs )
{
collidable::collidable_hit_function hit_func = lhs.get_hit_function();
return (lhs.*hit_func)( rhs );
}
其中函数check_object_collision是一个模板函数,用于测试碰撞并已经过测试。
我的问题如下:函数get_hit_function 中的强制转换确实可以编译,但似乎很可疑......我是否在做一些可怕的错误,这将导致未定义的行为和多个噩梦,或者可以强制转换模板成员函数指针从一个派生类到另一个派生类。
让我感到困惑的是,在 Visual c++ 2012 中,它可以编译并且 似乎 可以正常工作...
什么会让这个演员出现可怕的错误?
我不太明白转换函数指针意味着什么......
作为后续问题,是否有办法以安全的方式实现这一点
【问题讨论】:
-
不要依赖使用 msvc 和模板代码编译来告诉你太多。如果您正在使用 msvc(特别是),请编写一些测试并将类型传递到其中以确认编译。我们也遇到过类似的问题。
-
@dirvine 我已经运行了一些测试,但它似乎是一种问题很容易在导致明显症状之前隐藏很长时间的情况,我不想通过一周的时间来调试它一年...这就是为什么我不想依赖经验测试
-
这个双重派送怎么样?它似乎是在
lhs上单次调度,与您使用virtual do_collide方法没有什么不同。 -
@Yakk 它不是单一调度,因为一旦你执行了 hit 函数,“目标”就是使用两种几何类型执行
check_object_collision,一种来自this,另一种来自 @987654329 @ -
C++ 不在乎你的目标是什么。上面的代码没有双重分派,而且设计似乎不允许这样做。设计做单次分派,还不如直接
virtual方法:你添加的复杂性没有做任何事情。
标签: c++ templates c++11 function-pointers double-dispatch