0

Написал Шаблонный класс. Компилируется нормально. Как только в исполняющей функции объявляю что данные этого типа, то вылетает ошибка:

1>Бинарное дерево(1 вариант).obj : error LNK2019: ссылка на неразрешенный внешний символ "public: thiscall BinVector<int>::BinVector<int>(void)" (??0?$BinVector@H@@QAE@XZ) в функции _main 1>Бинарное дерево(1 вариант).obj : error LNK2019: ссылка на неразрешенный внешний символ "public: thiscall BinVector<int>::~BinVector<int>(void)" (??1?$BinVector@H@@QAE@XZ) в функции _main

Почему так? не могу понять( описал же правильно, вроде..

#include "stdafx.h"
#include "BinVector.h"
#include "iostream"
using namespace std;

int main() { BinVector<int> M; return 0; }

заголовок шаблона

#pragma once

template<class T> class BinVector { int len; class Element { T list; int left,right; Element(T t){list=t;left=-1;right=-1;} }; Element* Arr, BUF; void changeNombers(T t,int N=0);

public: BinVector(); ~BinVector(); T &operator [](int N); void push_back(T t); void pop(int N=len-1); void pop_back(){pop();} };

.срр

#include "stdafx.h"
#include "BinVector.h"

template<class T> BinVector<T>::BinVector(){len=0;};

template<class T> BinVector<T>::~BinVector(){};

template<class T> void BinVector<T>::push_back(T t) { BUF=new Element[++len]; for(int i=0; i<len-1) BUF[i]=Arr[i]; BUF[len-1]=t; delete Arr; Arr=BUF; if(len==0) return;//первому элементу указателей не надо. changeNombers(t);

return;

}

template<class T> void BinVector<T>::pop(int N) { bool b=false; BUF=new Element[--len]; for(int i=0;i<len;i++) { if(i==N)(b=true); BUF[i]=Arr[i+int(b)]; } Element buf=BUF; int LEN=len; for(int i=0;i<LEN;i++) push_back(buf[i]);

return;

}

template<class T> void BinVector<T>::changeNombers(T t,int N/=0/) { if (t<=Arr[N].list) if(Arr[N].left==-1) Arr[N].left=len-1; else changeNombers(t, Arr[N].left); else if(Arr[N].right==-1) Arr[N].right=len-1; else changeNombers(t, Arr[N].right); return; }

template<class T> T &BinVector<T>::operator [](int N) { if(N>=len||N<0) sleep(100000); return Arr[N].list; };

dIm0n
  • 407
andrw
  • 1,000
  • 1
    ошибка номер 1: реализация шаблонов должна быть в *.h а не *.cpp – ProkletyiPirat Apr 20 '13 at 15:57
  • @ProkletyiPirat, это не исправило ошибку...

    а почему реализация должна быть в *.h?

    – andrw Apr 20 '13 at 16:02
  • @andrw: Потому что шаблоны не компилируются. Шаблоны в C++ — не что иное, как продвинутый вариант макросов. Во время компиляции .cpp с шаблоном компилятор не знает, с каким параметром будет этот шаблон проинстанциирован, и, соответственно, не может его скомпилировать.

    Могу поспорить, когда вы перенесли реализацию шаблонов в .cpp, старая ошибка исчезла.

    – VladD Apr 20 '13 at 16:26
  • @VladD, с вами опасно спорить! да, исчезла.

    А описывать функции надо в нутри класса или достаточно просто скопировать из .cpp B .h?

    – andrw Apr 20 '13 at 16:39
  • @andrw: как вам больше нравится, в принципе, компилятору всё равно. Я обычно оставляю описания функций вне класса, чтобы выглядело похоже на обычный класс, но это исключительно вопрос личных предпочтений. – VladD Apr 20 '13 at 16:44
  • @VladD, Спасибо! – andrw Apr 20 '13 at 16:45

1 Answers1

0

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

В данном случае вы используете BinVector<int> M; в main.cpp, значит, и явная инстанциация должна быть для int в BinVector.cpp.

Синтаксис для явной инстанциации можно посмотреть в доках https://en.cppreference.com/w/cpp/language/class_template.

dIm0n
  • 407