user1808605
user1808605

Reputation: 1

Error: Invalid Use of Incomplete Type 'Class Stack<int>' [enabled by default]

I've been trying to put together a class template for a stack and a simple program to run through it and make sure it works. I keep getting this error when I compile (using MinGW) and I'm not sure what I'm doing wrong here. Thank you in advance.

Error:

In file included from Stacktemp_Driver.cpp:8:0:
stacktemp.h: In instantiation of 'class Stack<int>':
Stacktemp_Driver.cpp:23:14:   required from here
stacktemp.h:123:8: warning: invalid use of incomplete type 'class Stack<int>' [e
nabled by default]
stacktemp.h:16:7: warning: declaration of 'class Stack<int>' [enabled by default
]
stacktemp.h:153:6: warning: invalid use of incomplete type 'class Stack<int>' [e
nabled by default]
stacktemp.h:16:7: warning: declaration of 'class Stack<int>' [enabled by default
]

Here's my code for stacktemp.h:

#ifndef STACKTEMP_H
#define STACKTEMP_H
#include <stdlib.h>
#include <string>
#include <iostream>
#include <stdexcept>

template <class Type>
class Stack
{
 public:
  Stack();              //default constructor
  Stack(const Stack<Type> & a);//copy constructor
  ~Stack();                          //destructor
  Stack & operator=(Stack<Type> & a);//assignment operator
  bool operator!=(Stack<Type> & a);         //is not equal operator
  bool operator==(Stack<Type> & a);         //is equal operator
  Type & operator[](int subscript);         //subscript operator
  bool isfull() const;                      //determine if stack is full
  bool isempty() const;                     //determine if stack is empty
  bool push(Type item) throw(Stack*);      //add to top of the stack
  void outerpush() throw(std::overflow_error);
  bool pop(Type item) throw(Stack*);       //remove top of the stack
  void outerpop() throw(std::underflow_error);
  int capacity();                          //returns capacity of the stack
  int size();                              //returns size of the stack
  void print_stack();       //print the contents of the stack

 private:
  Type * data;                          
  int stack_size;                          //capacity of stack
  int tos;                                 //top of stack indicator
};


//constructors and destructor
template <class Type>
Stack<Type>::Stack()       //default constructor
{
  stack_size = 10;
  data = new Type[stack_size];
  tos = 0;
}

template <class Type>
Stack<Type>::Stack(const Stack<Type> & a)     //copy constructor
{
  stack_size = a.stack_size;
  data = new Type[stack_size];
  for (int i = 0; i < stack_size; i++)
    data[i] = a.data[i];
  tos = a.tos;
}

template <class Type>
Stack<Type>::~Stack()
{
  delete [] data;
}

//overloaded operators
template <class Type>
Stack<Type> & Stack<Type>::operator=(Stack<Type> & a)
{
  if (this == &a)
    return *this;
  delete [] data;
  stack_size = a.stack_size;
  data = new Type[stack_size];
  for (int i = 0; i < stack_size; i++)
    data[i] = a.data[i];
  tos = a.tos;
  return *this;
}

template <class Type>
Type & Stack<Type>::operator[](int subscript)
{
  if (subscript < 0 || subscript > (stack_size - 1))
    {std::cerr << "*** Out of range subscript = " << subscript << std::endl;
      exit(1);
    }
  return data[subscript];
}

template <class Type>
bool Stack<Type>::operator==(Stack<Type> & a)
{
  if (stack_size != a.stack_size)
    return false;
  for (int i = 0; i < stack_size; i++)
    {
      if (data[i] != a.data[i])
    return false;
    }
  return true;
}

//template class methods
template <class Type>
bool Stack<Type>::isfull() const
{
  return tos == stack_size;
}

template <class Type>
bool Stack<Type>::isempty() const
{
  if (tos == 0)
    return true;
  else
    return false;
}

template <class Type>
  bool Stack<Type>::push(Type item) throw(Stack*)
{
  if (isfull())
    throw this;
  data[tos] = item;
  tos = tos + 1;
  return true;
}

template <class Type>
void Stack<Type>::outerpush() throw(std::overflow_error)
{
  using std::cout;
  using std::cin;
  using std::endl;

  cout << "Please enter a value to place on top of stack: " << endl;
  Type item;
  cin >> item;
  try {
    this->push(item);
  }
  catch(Stack * dsx)
     {
      cout << "Error in ";
       throw std::overflow_error("Overflow error");
     }
}

template <class Type>
bool Stack<Type>::pop(Type item) throw(Stack*)
{
  if (isempty())
   throw this;
  tos = tos - 1;
   item = data[tos];
  return true;
}

template <class Type>
void Stack<Type>::outerpop() throw(std::underflow_error)
{
  using std::cout;
  using std::cin;
  using std::endl;

  Type item;
  try {
    this->pop(item);
  }
  catch(Stack * dsx)
  {
    cout << "Error in ";
    throw std::underflow_error("Underflow error");
  }
}

template <class Type>
int Stack<Type>::capacity()
{
  return stack_size;
}

template <class Type>
int Stack<Type>::size()
{
  return tos;
}

template <class Type>
void Stack<Type>::print_stack()
{
  for (int i = 0; i < tos; i++)
    std::cout << "a[" << i << "] = " << data[i] << std::endl;
}

#endif

Here's my code for Stacktemp_Driver.cpp:

#include "stacktemp.h"
#include <iostream>
#include <string>
#include <cstring>

void menu(void);

int main()
{
  using std::cout;
  using std::cin;
  using std::endl;
  using std::string;

  char* ans1;
  Stack<int> stack1;
  Stack<int> stack2;

  int ans;
  cin >> ans;

  while (ans != 8)
    {
      if (ans == 1)
    {
      stack1.print_stack();
      menu();
      cin >> ans;
    }
      else if (ans == 2)
    {
      try {
        stack1.outerpush();
      }
      catch(std::overflow_error &oe)
        {
          cout << oe.what() << endl;
          menu();
          continue;
        }
      menu();
      cin >> ans;
    }
      else if (ans == 3)
    {
      try {
        stack1.outerpop();
      }
      catch(std::underflow_error &ue)
        {
          cout << ue.what() << endl;
          menu();
          continue;
        }
      menu();
      cin >> ans;
    }
      else if (ans == 4)
    {
      int cap = stack1.capacity();
      cout << "The capacity of the stack is: " << cap << std::endl;
      menu();
      cin >> ans;
    }
      else if (ans == 5)
    {
      int sz = stack1.size();
      cout << "The size of the stack is: " << sz << std::endl;
      menu();
      cin >> ans;
    }
      else if (ans == 6)
    {
      stack2 = stack1;
      menu();
      cin >> ans;
    }
      else if (ans == 7)
    {
      if (stack1 == stack2)
        cout << "The stacks are equal." << endl;
      else
        cout << "The stacks are NOT equal." << endl;
      menu();
      cin >> ans;
    }
      else
    {
      cout << "Please enter an integer between 1 and 8.";
      menu();
      cin >> ans;
    }
    }

  return 0;
}


void menu()
{
  using std::cout;
  using std::cin;
  using std::endl;

  cout << "Please select from the following menu: (1-8)" << endl;
  cout << "1. Display stack" << endl;
  cout << "2. Place a double value onto the top of stack" << endl;
  cout << "3. Remove a value from the top of stack" << endl;
  cout << "4. Check the total capacity of the stack" << endl;
  cout << "5. Check the current number of items on stack" << endl;
  cout << "6. Copy stack to stack2" << endl;
  cout << "7. Check to see if stack and stack2 are equal" << endl;
  cout << "8. Quit" << endl;
}

Upvotes: 0

Views: 1851

Answers (1)

BЈовић
BЈовић

Reputation: 64223

As your compiler told you, the problem is next lines :

bool push(Type item) throw(Stack*);
bool pop(Type item) throw(Stack*);

The Stack is really incomplete type at that point.

The question is why do you throw a pointer to your class? Ideally, the throw type inherits from std::exception, or something that can provide you more information (like explained in this answer).

On the other hand, the throw specifications are deprecated.


btw here is a minimal example that exhibits the problem :

struct A
{
    void foo() throw( A* )
    {
        throw this;
    }
};

void menu()
{
    A a;
    a.foo();
}

Upvotes: 1

Related Questions