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