在我的collision/game physics engine中,我允许用户创建/指定首选的空间parititioning方法和首选的解决方法。
以下是空间分区的示例。
struct SpatialBase
{
virtual void a() = 0;
virtual void b() = 0;
...
};
struct Grid2D : public SpatialBase { ... override a() and b() ... };
struct QuadTree : public SpatialBase { ... override a() and b() ... };
struct World
{
std::vector<std::unique_ptr<Body>> bodies;
std::unique_ptr<SpatialBase> spatial;
...
World(SpatialBase* mSpatial, ...) : spatial(mSpatial), ... { }
};
auto world1{new World{new Grid2D{...}, ...}};
auto world2{new World{new QuadTree{...}, ...}};
这很好用,但动态多态完全没必要。事实上,World
的模板化版本太冗长了,因为还需要指定解析方法,Body
类必须知道它。
示例:
auto world1{new World<Grid2D, ImpulseRes>(...)}; // fine
auto& body1{world1.createBody()}; // still fine
void useBody(auto& mBody) { ... }
// illegal! Wish I could use auto& here.
void useBody(Body<Grid2D, ImpulseRes>& mBody) { ... }
// legal - but verbose, and what if the user decides to change
// spatial partitioning or resolution? All code would break.
有没有办法隐藏 Grid2D
和ImpulseRes
类型?只有在创建World
时才需要知道它们。但是Body
也必须知道这些类型,因为它需要引用空间分区方法实例和解析方法实例。
所需的代码示例:
World world1{new World<Grid2D, ImpulseRes>(...)};
Body& body1{world1.createBody()};
void useBody(Body& mBody) { ... }
答案 0 :(得分:1)
我认为你想要的是一个很好的老式typedef
。
typedef basic_world<grid2d, impulse_res> world;
typedef basic_body<world> body;
world world1(...);
void useBody(body& bdy) { ... };
答案 1 :(得分:1)
您可以使用
template <class TGrid, class TImpulse>
void useBody(Body<TGrid, TImpulse>& mBody) { ... }
或
template <class TBody>
void useBody(TBody& mBody) { ... }
答案 2 :(得分:0)
我不知道你的代码是如何分区的,但如果你在实例化body1
之后声明你的函数,也许你可以使用decltype
:
auto& body1 = world1.createBody();
using body_type = decltype(body1);
void useBody(body_type& b) { ... }