Проблема спецификации шаблона - PullRequest
1 голос
/ 03 сентября 2011

Я пытаюсь сделать следующее: файл определения класса h:

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

файл определения класса cpp для формирования функции (все остальные одинаковые):

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

использование:

    Sculptor<16> sclupt;

Shape shape;

SculptData* data = CreateCircle();


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

и я получаю следующую ошибку enter image description here

Не могли бы вы показать мне источник проблемы?

Ответы [ 4 ]

3 голосов
/ 03 сентября 2011

Помните, что реализация класса шаблона должна быть видна из модуля компиляции, который его использует.В частности, вы не можете поместить реализацию в отдельный файл .cpp (как это принято в классах, не относящихся к шаблонам), но вместо этого следует поместить его в заголовочный файл, где был объявлен шаблон.

3 голосов
/ 03 сентября 2011

99% времени LNK2019 означает, что вы забыли фактически полностью определить тело функции или класса, который вы где-то использовали. Где реализация ToShape(), Sculp() и CalculateMesh()?Как насчет конструктора и деструктора ?

Похоже, что вы помещаете реализации в файл .cpp.Понятно, что интерфейс следует отделять от реализации, но шаблоны классов - это совершенно разные звери от не шаблонов.

На самом деле компилятор не генерирует машинный код для шаблонов, поскольку не все параметры шаблона имеютбыли определены еще.Вы не можете сгенерировать машинный код для Sculptor, не зная, например, насколько большим будет массив-член.Компилятор не знает заранее, что Size == 16 когда компилятор приступает к разбору определения шаблона.Таким образом, вы получаете ошибки компоновщика, так как компоновщик не может найти машинный код для него;его не существует!

Для шаблонных классов вы обычно помещаете реализацию в самом объявлении класса шаблона , так что вы, вероятно, действительно упускаете определения функций , например:

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

    // and so on...

Шаблоны в библиотеках Boost и стандартной библиотеке C ++ определены следующим образом.


Примечание: с Size == 16 вы создаете массив 3x3 с 4096unsigned char с в нем.Хотя это само по себе не является проблемой, переполнение стека довольно легко, когда один Sculptor занимает не менее 4096 unsigned char с в стеке.

1 голос
/ 03 сентября 2011

Вы забыли написать код для ToShape, Sculp, CalculateMesh, конструктора и деструктора.Реализуйте их или добавьте фиктивную реализацию, и программа свяжется.

Кроме того:

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

не является допустимым C ++ (если массив не определен как void), вы имели в виду это вместо этого?

unsigned char sculpture[Size][Size][Size];
0 голосов
/ 03 сентября 2011

Шаблоны должны быть полностью определены во всех единицах перевода, в которых они используются - вы не можете их связать. Это означает, что компилятор не может найти тело функций, которые вы вызываете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...