stack.cpp
//stack.cpp
#include "stack.h"
template <class T>
Stack<T>::Stack()
{
top = nullptr;
}
template <class T>
void Stack<T>::push(T arg)
{
Node* temp = new Node;
temp->value = arg;
temp->next = top;
top = temp;
}
template <class T>
T Stack<T>::pop()
{
if (top != nullptr)
{
T result = top->value;
Node* temp = top;
top = top->next;
delete temp;
return result;
} else
return 0;
}
template <class T>
Stack<T>::~Stack()
{
while (top != nullptr)
pop();
}
stack.h
//stack.h
#ifndef PROJECT_STACK_H
#define PROJECT_STACK_H
template <class T>
class Stack
{
private:
struct Node
{
T value;
Node* next;
};
Node* top;
public:
Stack();
void push(T arg);
T pop();
~Stack();
};
#endif //PROJECT_STACK_H
//main.cpp примерно следующего содержания:
Stack <char> s;
s.push('a');
компилирую через g++ так: g++ -std=c++11 main.cpp stack.cpp
Получаю следующие ошибки:
/tmp/ccvtzAEt.o:main.cpp:(.text+0x1b): undefined reference to `Stack<char>::Stack()'
/tmp/ccvtzAEt.o:main.cpp:(.text+0x1b): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Stack<char>::Stack()'
/tmp/ccvtzAEt.o:main.cpp:(.text+0x2c): undefined reference to `Stack<char>::push(char)'
/tmp/ccvtzAEt.o:main.cpp:(.text+0x2c): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Stack<char>::push(char)'
/tmp/ccvtzAEt.o:main.cpp:(.text+0x3d): undefined reference to `Stack<char>::push(char)'
/tmp/ccvtzAEt.o:main.cpp:(.text+0x3d): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Stack<char>::push(char)'
/tmp/ccvtzAEt.o:main.cpp:(.text+0x49): undefined reference to `Stack<char>::pop()'
/tmp/ccvtzAEt.o:main.cpp:(.text+0x49): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Stack<char>::pop()'
/tmp/ccvtzAEt.o:main.cpp:(.text+0x66): undefined reference to `Stack<char>::pop()'
/tmp/ccvtzAEt.o:main.cpp:(.text+0x66): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Stack<char>::pop()'
/tmp/ccvtzAEt.o:main.cpp:(.text+0x9b): undefined reference to `Stack<char>::~Stack()'
/tmp/ccvtzAEt.o:main.cpp:(.text+0x9b): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Stack<char>::~Stack()'
/tmp/ccvtzAEt.o:main.cpp:(.text+0xae): undefined reference to `Stack<char>::~Stack()'
/tmp/ccvtzAEt.o:main.cpp:(.text+0xae): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Stack<char>::~Stack()'
collect2: ошибка: выполнение ld завершилось с кодом возврата 1
То есть undefined reference to Stack<char>::Stack()
и undefined reference to Stack<char>::push(char)
и undefined reference to Stack<char>::~Stack()
В чем проблема? Заранее огромное спасибо!
Ну откуда же при компиляции stack.cpp компилятору знать, что где-то, в совсем другом файле вам понадобится Stack<char>
?
Не выносите реализацию шаблонов в отдельный файл, оставляйте ее в заголовочном файле.
Либо не выносите определения шаблонов в отдельный файл (т.е. реализуйте все в заголовочном файле), либо не забывайте включать этот отдельный файл повсеместно, как включаются обычные заголовочные файлы.
На практике у обоих подходов есть свои поклонники. Но при этом давать файлу реализации расширение .cpp
не принято - это все таки включаемый, а не отдельно компилируемый файл.
Скармливать ваш файл реализации непосредственно компилятору (g++ stack.cpp
) бесполезно: определения шаблонов не порождают кода, в чем вы сможете убедиться взглянув на сгенерированный из stack.cpp
объектный файл - он будет пуст.
P.S. Теоретически, вы можете оставить все как есть, но добавить в stack.cpp
явные инстанциации вашего шаблона для всех требуемых типов аргументов. Т.е. в вашем случае достаточно добавить в stack.cpp
строчку
template Stack<char>;
и все сразу заработает в оригинальном виде, при компиляции через ваше g++ -std=c++11 main.cpp stack.cpp
. Но, как вы сами понимаете, в общем случае это - не жизнеспособный подход, а специальная фича, предназначенная совсем для других целей.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Набор аргументов для которых необходимо найти интерполируемые значения(t1):
Доброго времени суток! Нужно перегрузить оператор + для сложение двух двумерных массивовПыталась перегрузить так, но это вызывает исключение
Подскажите библиотеку на C++ в которой реализован метод интерполяции с регулярной сетки на сетку ВороногоКак я понял нужно искать все пересечения...