2

I meet a problem when using mingw32-g++ to compile a pj in codeblocks.

error msgs

obj\Debug\main.o||In function `main':|
E:\project\test\main.cpp|15|undefined reference to `Stack<char>::Stack()'|
E:\project\test\main.cpp|23|undefined reference to `Stack<char>::shiftL()'|
E:\project\test\main.cpp|28|undefined reference to `Stack<char>::shiftR()'|
E:\project\test\main.cpp|33|undefined reference to `Stack<char>::Del()'|
E:\project\test\main.cpp|36|undefined reference to `Stack<char>::push(char)'|
||error: ld returned 1 exit status|
||=== Build failed: 6 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

Stack.h

#ifndef STACK_H_INCLUDED
#define STACK_H_INCLUDED

template <class Type>
struct List
{
    Type content;
    List<Type> *head;
    List<Type> *end;
};

template <class Type>
class Stack
{
public:
    Stack();
    ~Stack(){};
    void push(Type x);
    void Del();
    void shiftL();
    void shiftR();
    List<Type> *Front(){ return front; }
    List<Type> *Back(){ return back; }
private:
    List<Type> *front;
    List<Type> *back;
    List<Type> *operate;
    List<Type> F;
    List<Type> B;
    int pos;
};
#endif // STACK_H_INCLUDED

Stack.cpp

#include"Stack.h"
#include<stdio.h>
template<class Type>
Stack<Type>::Stack()
{
    F.head = B.end = NULL;
    front = &F;
    back = &B;
    front->end = &B;
    back->head = &F;
    operate = back;
    pos = 0;
}
template<class Type>
void Stack<Type>::Del()
{
    if (pos>0)
    {
        List<Type>* temp;
        temp = operate;
        operate = operate->end;
        operate->head = temp->head;
        temp->head->end = operate;
        pos--;
    }
}
template<class Type>
void Stack<Type>::shiftL()
{
    if (pos>0)
    {
        operate = operate->end;
        pos--;
    }

}
template<class Type>
void Stack<Type>::shiftR()
{
    if (operate->head != front)
    {
        operate = operate->head;
        pos++;
    }
}
template<class Type>
void Stack<Type>::push(Type x)
{

    List<Type>* temp;
    temp = new List<Type>;
    temp->content = x;
    temp->end = operate;
    temp->head = operate->head;
    operate->head->end = temp;
    operate->head = temp;
    operate = operate->head;
    pos++;
}

mian.cpp

#include<stdio.h>
#include<iostream>
#include"Stack.h"
using namespace std;

int main()
{
    char c;
    int k;
    cin >> k;
    getchar();
    for (int j = 0; j < k; j++)
    {
        Stack<char> password;
        while (1)
        {
            c = getchar();
            if (c == '\n')
                break;
            if (c == '<')
            {
                password.shiftL();
                continue;
            }
            if (c == '>')
            {
                password.shiftR();
                continue;
            }
            if (c == '-')
            {
                password.Del();
                continue;
            }
            password.push(c);
        }

            List<char>* i;
            for (i = password.Back()->head; i != password.Front(); i = i->head)
                printf("%c", i->content);
            printf("\n");
    }
    return 0;
}

But

If I add #include"Stack.cpp" in main.cpp(this is illegal,right?),the complier don't show any errors or warnings.
Can you tell me why?Thanks a lot! :)

Hz Shang
  • 105
  • 1
  • 9

1 Answers1

0

Given Stack is a template the compiler cannot generate it at link time, it needs to know what template arguments it will be instantiated with at compile time.

You have a few ways of doing this. The first is to move the function definitions into the header file (or equivalently include the cpp file in the header which is legal). At the end of Stack.h:

#include "Stack.cpp"

The other is to perform explicit template instantiation where you tell the compiler all the template arguments which might be used in stack.cpp which will then allow it to generate them at compile time and link normally. At the end of Stack.cpp:

template class Stack<char>;
Vality
  • 6,577
  • 3
  • 27
  • 48
  • I find another way. Just change `Stack.cpp` to `Stack.hpp` and add `#include"Stack.hpp"` in `Stack.h` easily ,then the complier will precompile it. Anyway,Thank you! :) – Hz Shang Oct 19 '16 at 09:22