简体   繁体   English

避免在编译时使用已知类型的模板冗长和动态多态

[英]Avoiding template verbosity and dynamic polymorphism with types known at compile-time

In my collision/game physics engine , I allow the user to create/specify a preferred spatial parititioning method and a preferred resolution method. 在我的碰撞/游戏物理引擎中 ,我允许用户创建/指定首选的空间划分方法和首选的分辨率方法。

Here's an example with spatial partitioning. 这是一个空间分区的例子。

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{...}, ...}};

This works fine, but the dynamic polymorphism is completely unnecessary. 这可以正常工作,但是动态多态性完全没有必要。 Fact is, a templatized version of World would be too verbose, as a resolution method also needs to be specified, and the Body class must be aware of it. 事实是, World的模板化版本太冗长,因为还需要指定解析方法,并且Body类必须意识到这一点。

Example: 例:

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.

Is there a way to hide the Grid2D and ImpulseRes types? 有没有办法隐藏 Grid2DImpulseRes类型? They only need to be known when the World is created. 仅在创建World时才需要知道它们。 But Body must also be aware of those types, as it needs a reference to the spatial partitioning method instance and the resolution method instance. 但是, Body还必须意识到这些类型,因为它需要引用空间分区方法实例和解析方法实例。

Desired code example: 所需的代码示例:

World world1{new World<Grid2D, ImpulseRes>(...)};
Body& body1{world1.createBody()}; 

void useBody(Body& mBody) { ... }     

I think what you want is a good old-fashioned typedef . 我认为您想要的是一个很好的老式typedef

typedef basic_world<grid2d, impulse_res> world;
typedef basic_body<world> body;

world world1(...);
void useBody(body& bdy) { ... };

You may use 您可以使用

template <class TGrid, class TImpulse>
void useBody(Body<TGrid, TImpulse>& mBody) { ... } 

or 要么

template <class TBody>
void useBody(TBody& mBody) { ... } 

I don't know how your code is partitioned, but if you declare your function after instantiating body1 , maybe you could use decltype : 我不知道您的代码如何分区,但是如果您在实例化body1之后声明函数,也许可以使用decltype

auto& body1 = world1.createBody();

using body_type = decltype(body1);

void useBody(body_type& b) { ... }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM