C ++如何用模板规范或其他方式实现?

时间:2016-04-18 02:31:10

标签: c++ templates generic-programming

我正在实现一个Boundary Volumn Hierarchy结构,其中树有一个这样的模板:

template <typename Coordinate> 
class BoundingTree { /* ... */ }

Coordinate可以是Vector2dVector3f或任何其他任意坐标。要使用此BoundingTree结构进行碰撞检测,应该有一个检测功能:

template <typename Coordinate> 
template <typename RigidBody>
bool BoundingTree::collide(RigidBody const & body);

RigidBody可以是一切,例如Cuboid3fCircle2d。我对这个检测系统的实现是:

// BoundingTree.h
template <typename Coordinate>
class BoundingTree
{
public:
    BoundingTree() {}

    // collide function decleration
    template <typename RigidBody>
    bool collide(RigidBody const & obj);

};

// BoundingTree.cpp
// specilizations
template<typename Coordinate> template <typename RigidBody>
bool BoundingTree::collide(RigidBody const & obj)
{
    std::cout << "default" << std::endl;
    return false;
}

template<> template<>
bool BoundingTree<Vector3f>::collide<Sphere3f>(Sphere3f const & d)
{
    std::cout << "Vector3f Sphere3f" << std::endl;
    return 1;
};

template<> template<>
bool BoundingTree<Vector3f>::collide<Cuboid3f>(Cuboid3f const & d)
{
    std::cout << "Vector3f Cuboid3f" << std::endl;
    return 1;
};

但我得到了一个错误:

1>BoundingTree.cpp(6): error C2955: 'BoundingTree': use of class template requires template argument list
1>  BoundingTree.h(32): note: see declaration of 'BoundingTree'
1>BoundingTree.cpp(10): error C2244: 'BoundingTree::collide': unable to match function definition to an existing declaration
1>  BoundingTree.cpp(6): note: see declaration of 'BoundingTree::collide'

如何解决这个问题?

有没有更好的方法来实现任意类型的碰撞检测系统?

非常感谢。

1 个答案:

答案 0 :(得分:1)

您要执行的操作is allowed但是您遇到语法错误:

template<typename Coordinate> template <typename RigidBody>
bool BoundingTree::collide(RigidBody const & obj)
                         ^

这不是专业化,所以你必须为类指定模板参数,它应该是

bool BoundingTree::collide<Coordinate>(...)

但我发现你的代码被分成了标题和源代码,这可能会导致你的代码非专业化的问题。

如果在源文件中定义模板化函数但在另一个转换单元中使用,则在编译期间不会生成模板的实例化,并且会出现链接器错误。

完全专业化不会发生这种情况,例如

template<> template<>
bool BoundingTree<Vector3f>::collide<Sphere3f>(Sphere3f const & d)

但是如果您计划进行部分特化,那么您将被迫移动头文件中的所有内容或强制在定义它们的源文件中实例化模板,例如

template class BoundingTree<MyCoord>;
template bool BoundingTree<MyCoord>::collide<MyShape>(MyShape const& d);