Sergey Kucher
Sergey Kucher

Reputation: 4180

Template specification problem

I am trying to do the folllowing: class definition h file:

template<int Size>
class Sculptor
{
public:
    Sculptor();

    ~Sculptor(void) ;

    void Sculp(SculptData* sculpData);

    void ToShape(Shape* shape);

    int CalculateMesh();

    unsigned char sculpture[Size][Size][Size];
}

class definition cpp file to shape function (all others are the same):

template<int Size>
void Sculptor<Size>::ToShape(Shape* shape){}

usage:

    Sculptor<16> sclupt;

Shape shape;

SculptData* data = CreateCircle();


sclupt.Sculp(data);
sclupt.CalculateMesh();
sclupt.ToShape(&shape);

and I get the following error enter image description here

Could you please show me the source of the problem ?

Upvotes: 1

Views: 349

Answers (4)

In silico
In silico

Reputation: 52207

99% of the time a LNK2019 means that you forgot to actually fully define the body of a function or a class that you've used somewhere. Where's the implementation for ToShape(), Sculp(), and CalculateMesh()? What about the constructor and the destructor?

It appears that you are putting the implementations into a .cpp file. While it is understandable that one should separate the interface from the implementation, class templates are completely different beasts from non-templates.

The compiler doesn't actually generate any machine code for templates because not all the template parameters have been defined yet. You can't generate the machine code for Sculptor without knowing how big the member array is going to be, for example. The compiler doesn't know in advance that Size == 16 when the compiler comes to parsing the template definition. So you get linker errors since the linker can't find the machine code for it; it doesn't exist!

For template classes you would typically put the implementation in the template class declaration itself, so you're probably really are missing those function definitions like this:

template<int Size> 
class Sculptor 
{ 
public: 
    Sculptor()
    {
        // implementation
    }

    // and so on...

The templates in the Boost libraries and the C++ Standard Library are defined like this.


A side note: with Size == 16, you're creating a 3x3 array with 4096 unsigned chars in it. While that's not a problem in of itself, it's quite easy to overflow the stack when a single Sculptor occupies at least 4096 unsigned chars on the stack.

Upvotes: 3

Puppy
Puppy

Reputation: 147036

Templates must be fully defined in all translation units in which they are used- you can't link them in. This means that the compiler cannot find the body of the functions you are calling.

Upvotes: 0

ComicSansMS
ComicSansMS

Reputation: 54737

Remember that the implementation of a template class must be visible from the compilation unit that uses it. In particular, you may not place the implementation into a separate .cpp file (as is common practice with non-template classes) but instead should place it in the header file where the template was declared.

Upvotes: 3

Karel Petranek
Karel Petranek

Reputation: 15164

You forgot to write the code for ToShape, Sculp, CalculateMesh, constructor and destructor. Implement them or add a dummy implementation and the program will link.

Also:

unsigned char array sculpture[Size][Size][Size];

is not valid C++ (unless array is some void define), did you mean this instead?

unsigned char sculpture[Size][Size][Size];

Upvotes: 1

Related Questions