在我的碰撞/物理引擎中,我知道我在运行时使用的空间分区方法,这要归功于模板。我正在尝试创建一个通用Query
类,它允许我对任何空间分区方法执行相同的查询。每个空间分区方法都实现了自己的查询版本,但接口是相同的。
问题是用户必须指定空间分区类型、空间分区类型的查询类型和空间分区类型的查询模式。
如果用户改变其空间划分方法,所有现有代码都会中断。
有没有办法让用户只指定空间分区类型、通用查询类型和通用查询模式并具有某种别名以便自动选择正确的类型(相对于空间分区类型)?
我已经尝试过using
(C++11 typedef
) 以及decltype
部分专业化,但是我找不到编写代码的正确方法,而且我从来没有让它编译/工作。
我只能考虑使用virtual
方法和基类——但这似乎没有必要,因为我在编译时“知道”类型。
当前代码:
// Query.h
template<class T, class U, class V>
Query<T, U, V> getQuery() { return Query<T, U, V>(getSpatial<T>()); }
// Example.cpp (user project)
getQuery<Grid, GridQueryType::Point, GridQueryMode::All>();
getQuery<QuadTree, QuadTreeQueryType::Point, QuadTreeQueryMode::All>();
所需代码(无效):
// Query.h
namespace Type { struct Point; }
namespace Mode { struct All; }
template<class T, class U, class V>
Query<T, typename T::U, typename T::V> getQuery()
{
return Query<T, typename T::U, typename T::V>(getSpatial<T>());
}
// Grid.h
using Type::Point = GridQueryType::Point;
using Mode::All = GridQueryMode::All;
// QuadTree.h
using Type::Point = QuadTreeQueryType::Point;
using Mode::All = QuadTreeQueryMode::All;
// Example.cpp (user project)
getQuery<Grid, Type::Point, Mode::All>(); // actually uses GridQueryType::Point and GridQueryMode::All!
getQuery<QuadTree, Type::Point, Mode::All>(); // actually uses QuadTreeQueryType::Point and QuadTreeQueryMode::All!
实际代码也传递typename... TArgs
以允许特定于查询类型的参数 - 由于空间原因,我将其从示例中排除。