0

I am implementing a Boundary Volumn Hierarchy structure, where the tree has a template like this:

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

The Coordinate can be Vector2d, Vector3f or any other arbitrary coordinate. To use this BoundingTree structure for collision detection, there should be an detection function:

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

The RigidBody can be everything, e.g. Cuboid3f, Circle2d. And my implementation of this detection system is:

// 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;
};

But I got an Error:

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'

How to solve this problem?

Is there any better manner to implement this collision detection system with arbitrary types?

Thanks a lot.

stanleyerror
  • 728
  • 1
  • 9
  • 23
  • Where is line 6 of BoundingTree.cpp in your post? `BoundingTree::collide` has two `template ` clauses before it. This is syntactically wrong. – Ivan Aksamentov - Drop Apr 18 '16 at 02:36
  • Apart of the syntax issue, you cannot, generally, split templates into header and source files. See: [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file?rq=1) – Ivan Aksamentov - Drop Apr 18 '16 at 02:38

1 Answers1

1

What you are trying to do is allowed but you have a syntax error which is here:

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

This is not a specialization so you must specify the template argument for the class, it should be

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

But I see that your code is split into header and source, this can create problem with non specialization of your code.

If a templated function is defined inside a source file but used in another translation unit, then the instantiations of the template won't be generated during compilation and you'll get linker errors.

This won't happen with full specializations, like

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

But if you plan to have partial specializations then you will be forced to move everything in the header file or force the instantiation of the template in the source file that defines them, eg

template class BoundingTree<MyCoord>;
template bool BoundingTree<MyCoord>::collide<MyShape>(MyShape const& d);
Jack
  • 131,802
  • 30
  • 241
  • 343
  • I believe the correct syntax is actually: "template template bool BoundingTree::collide(RigidBody const & obj)", at least according to gcc 5.3.1 – Sam Varshavchik Apr 18 '16 at 02:49
  • @SamVarshavchik: On clang 3.4 this compiles and executes correctly, but I'm too tired to open the standard right now. – Jack Apr 18 '16 at 02:51
  • @Jack with all these in one header file, I got an error of `one or more multiply defined symbols found` when multiple included. Did I make it wrong? – stanleyerror Apr 18 '16 at 03:26
  • @Jack Oh I fixed it by making all template definitions and the specilization functions' declerations in the header, and put the specilization functions' definition in the cpp. There is no error then. – stanleyerror Apr 18 '16 at 05:27