Thread: What could be wrong about this template?

  1. #1
    Registered User
    Join Date
    Dec 2004
    Location
    Ankara, Turkey
    Posts
    18

    Unhappy What could be wrong about this template?

    Code:
    StackA.h
    
    #ifndef STACKA_H
    #define STACKA_H
    // *********************************************************
    // Header file StackA.h for the ADT stack.
    // Array-based implementation.
    // *********************************************************
    #include "StackException.h"
    #include 
    const int MAX_STACK = 100;
    
    template < class StackItemType >
    
    class Stack
    {
    public:
    // constructors and destructor:
    Stack(); // default constructor
    
    // stack operations:
    bool isEmpty() const;
    void push(StackItemType newItem) throw(StackException);
    void pop() throw(StackException);
    void pop(StackItemType& stackTop) throw(StackException);
    void getTop(StackItemType& stackTop) const
    throw(StackException);
    
    private:
    StackItemType items[MAX_STACK]; // array of stack items
    int top; // index to top of stack
    }; // end class
    
    #endif
    
    StackA.cpp
    
    // *********************************************************
    // Implementation file StackA.cpp for the ADT stack.
    // Array-based implementation.
    // *********************************************************
    #include "StackA.h" // Stack class specification file
    #include "StackException.h"
    
    template < class StackItemType >
    Stack::Stack(): top(-1)
    {
    } // end default constructor
    
    template < class StackItemType >
    bool Stack::isEmpty() const
    {
    return top < 0;
    } // end isEmpty
    
    template < class StackItemType >
    void Stack::push(StackItemType newItem) throw(StackException)
    {
    // if stack has no more room for another item
    if (top >= MAX_STACK-1)
    throw StackException("StackException: stack full on push");
    else
    { ++top;
    items[top] = newItem;
    } // end if
    } // end push
    
    template < class StackItemType >
    void Stack::pop() throw(StackException)
    {
    if (isEmpty())
    throw StackException("StackException: stack empty on pop");
    else
    --top; // stack is not empty; pop top
    } // end pop
    
    template < class StackItemType >
    void Stack::pop(StackItemType& stackTop) throw(StackException)
    {
    if (isEmpty())
    throw StackException("StackException: stack empty on pop");
    else
    { // stack is not empty; retrieve top
    stackTop = items[top];
    --top; // pop top
    } // end if
    } // end pop
    
    template < class StackItemType >
    void Stack::getTop(StackItemType& stackTop) const throw(StackException)
    {
    if (isEmpty())
    throw StackException("StackException: stack empty on getTop");
    else
    // stack is not empty; retrieve top
    stackTop = items[top];
    } // end getTop
    // End of implementation file.
    in main function of a driver class,

    Code:
    Stack< char > myStack;
    The Visual Studio 2005 compiler gives me 6 errors that I cannot understand anything from them.
    Here some of them;

    Error 22 error LNK2019: unresolved external symbol "public: bool __thiscall Stack::isEmpty(void)const " (?isEmpty@?$Stack@D@@QBE_NXZ) referenced in function "class std::basic_string,class std::allocator > __cdecl convertInfixToPostfix(class std::basic_string,class std::allocator >)" (?convertInfixToPostfix@@YA?AV?$basic_string@DU?$c har_traits@D@std@@V?$allocator@D@2@@std@@V12@@Z) InfixCalculator

    Error 23 error LNK2019: unresolved external symbol "public: void __thiscall Stack:op(void)" (?pop@?$Stack@D@@QAEXXZ) referenced in function "class std::basic_string,class std::allocator > __cdecl convertInfixToPostfix(class std::basic_string,class std::allocator >)" (?convertInfixToPostfix@@YA?AV?$basic_string@DU?$c har_traits@D@std@@V?$allocator@D@2@@std@@V12@@Z) InfixCalculator

    Error 27 fatal error LNK1120: 5 unresolved externals InfixCalculator


    Any help would be appriciated,
    Thanks in advance.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    If everything is in the templates, then I don't think you need a stack.cpp file.
    You do however need to include "stack.h" in your main.cpp, so it knows what to do when it sees the
    Code:
    Stack< char > myStack;
    The compiler needs the templates in scope in order to generate a char version of your stack.

  3. #3
    Registered User
    Join Date
    Dec 2004
    Location
    Ankara, Turkey
    Posts
    18
    But if I don't use StackA.cpp, how can the compiler understand what is inside of my functions? The StackA.h only holds function prototypes.

    Thanks,

  4. #4
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    When you have a template function it acts like a blueprint for the compiler. You compiler will generate the actual code and put it with the object file at compile time. Due to the limitations of most compilers your header file should contain the full template defination.

  5. #5
    Registered User
    Join Date
    Dec 2004
    Location
    Ankara, Turkey
    Posts
    18
    Then Mr.Miill you mean, should I define all the functions in StackA.h and delete the StackA.cpp file?

    Do you have any example for me to see how these templates work? (I don't know templates much)

    Thanks,

  6. #6
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Pretty much yes. Unless of course you declare some non template stuff in StackA.h, which should then be defined in StackA.cpp
    Example hmm:
    foo.h
    Code:
    #ifndef FOO_H_
    #define FOO_H_
    template<typename T>
    T greater(T x, T y)
    {
      if ( x > y )
        return x;
      return y;
    }
    
    bool isgreater( int x, int y);
    #endif;
    foo.cpp
    Code:
    bool isgreater (int x, int y)
    {
      return x > y;
    }
    bar.cpp
    Code:
    #include <iostream>
    #include "foo.h"
    using namespace std;
    
    int main()
    {
      int x=5, y=3;
      cout<<"X = "<<x<<" Y = "<<y<<endl;
      cout<<"The greater value is"<<greater(x,y)<<endl;
      cout<<"X is greater then Y: "<<isgreater(x,y)<<endl;
    }

  7. #7
    Registered User
    Join Date
    Dec 2004
    Location
    Ankara, Turkey
    Posts
    18
    I got the example but I couldn't apply it to my example
    Sarp Arda Coskun
    www.bilgiciftligi.com

  8. #8
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    You basically need to combine what was in your StackA.h and StackA.cpp files into one StackA.h file. So, just copy everything that was in the cpp file and paste it into what you've already got in the h file (at the end, after your class declaration) and then delete the StackA.cpp file.

    Incidentally, you can make your template a bit more flexible in regards to the size of the array used to store your values. Currently you have a const int variable MAX_STACK that defines the size of the array. The problem is if you want to resize this array, you still need to change the value and recompile the code to get that new size. You can instead pass the size as an additional template parameter so the size gets set when you create your Stack objects. You can even define a default size (that would take place of the current const int MAX_STACK setup you have so if you decline to specify a size when you create your object, the default size is used. As an example:

    Code:
    #include <iostream>
    
    template <typename T,int MAX_SIZE = 20>
    class Stack {
        public:
            T values[MAX_SIZE];
            int GetSize() const { return MAX_SIZE; }
    };
    
    int main()
    {
        Stack<int,50> StackI;
        Stack<double,100> StackD;
        Stack<float> StackF;
    
        std::cout << StackI.GetSize() << std::endl;
        std::cout << StackD.GetSize() << std::endl;
        std::cout << StackF.GetSize() << std::endl;
    
        return 0;
    }
    This should output:
    Code:
    50
    100
    20
    As you can see, the first two objects StackI and StackD get values specified for how big the array should be. The last object however, StackF, gets no size specified so therefore my default of 20 gets used instead.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  9. #9
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    Kromozom, may I enquire as to the reason why I have been added to your MSN Contact List?

  10. #10
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    this might be part of the problem

    #include "StackException.h"
    #include
    const int MAX_STACK = 100;
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  11. #11
    Registered User
    Join Date
    Dec 2004
    Location
    Ankara, Turkey
    Posts
    18
    misplaced there is
    Code:
    #include < new >
    however, while I'm copying it here the site editor seems that as a HTML tag as far as I see, thanks.

    I thought that may be you can help me on some crucial points while learning C++, Sean.

    hk_mp5kpdw, thank you very much it worked.
    Sarp Arda Coskun
    www.bilgiciftligi.com

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Template Typedef how to?
    By ashcan1979 in forum C++ Programming
    Replies: 2
    Last Post: 11-28-2006, 05:48 AM
  2. Nested loop frustration
    By caroundw5h in forum C Programming
    Replies: 14
    Last Post: 03-15-2004, 09:45 PM
  3. Template specialization
    By CornedBee in forum C++ Programming
    Replies: 2
    Last Post: 11-25-2003, 02:02 AM
  4. God
    By datainjector in forum A Brief History of Cprogramming.com
    Replies: 746
    Last Post: 12-22-2002, 12:01 PM
  5. templates with pointers
    By Cipher in forum C++ Programming
    Replies: 3
    Last Post: 11-18-2002, 11:45 AM