//This code tells us what happens in the scope of Stack
#include <iostream>
usingnamespace std ;
#include "stack.hh" //the header file declares Stack
void Stack::push(double c) {
if (full()) {
cout << "Stack::push() the Stack is getting 10 more elements" << endl ;
_s.resize(_s.size()+10);
}
_s[count++] = c ;
}
double Stack::pop() {
if (empty()) {
cout << "Stack::pop() Error: stack is empty" << endl ;
return 0 ;
}
return _s[--count] ;
}
void Stack::inspect() { // an inspection function that prints the
int i; // stack contents in the right order and
for(i=count-1 ; i>=0 ; i--){ // and gives the value of the stack content
cout<< "[" << i << "] = " << _s[i] << endl;
}
}
Stack::Stack(int length, double def)
{
Array<def> _s(int length, def);
}
and it uses this code for the template function Array:
#include<iostream>
#ifndef ARRAY_HH
#define ARRAY_HH
usingnamespace std;
template <class T>
class Array {
public:
Array(int size, T def) : _size(size), _arr(0), blank(def) { //Making and Filling up the array with default values
_arr = new T[_size] ;
for(int i=0; i<_size ; i++){
_arr[i] = blank ;
}
}
Array(const Array<T>& other) : _size(other._size) { //copying an array into a new array
_arr = new T[other._size] ;
// Copy elements
for (int i=0 ; i<_size ; i++) {
_arr[i] = other._arr[i] ;
}
}
~Array() { //destructor
delete[] _arr ;
}
Array<T>& operator=(const Array<T>& other)
{
if (&other==this) return *this ;
if (_size != other._size) {
resize(other._size) ;
}
for (int i=0 ; i<_size ; i++) {
_arr[i] = other._arr[i] ;
}
}
T& operator[](int index) { //when an element beyond the range of the array is accessed, this operator resizes the array so the called for element is included in the array
if(index >= _size) {
resize(index + 1);
}
return _arr[index] ;
}
const T& operator[](int index) const {
if(index >= _size) {
resize(index + 1);
}
return _arr[index] ;
}
int size() const { return _size ; }
void resize(int newSize) //resizing the array to the desired length
{
// Allocate new array
T* newArr = new T[newSize] ;
// Copy elements
for (int i=0 ; i< _size ; i++) {
newArr[i] = _arr[i] ;
}
for(int i = _size; i < newSize ; i++ ){ //filling up the undefined elements with default values
newArr[i] = blank;
}
// Delete old array and install new one
if (_arr) {
delete[] _arr ;
}
_size = newSize ;
_arr = newArr ;
}
private:
int _size ;
T* _arr ;
T blank;
} ;
#endif
I also have a header file and a main, but they don't give any trouble.
when i try to compile it, I get this error message:
1 2 3 4 5 6 7 8
stack.cc: In constructor ‘Stack::Stack(int, double)’:
stack.cc:31: error: no matching function for call to ‘Array<double>::Array()’
Array.hh:18: note: candidates are: Array<T>::Array(const Array<T>&) [with T = double]
Array.hh:11: note: Array<T>::Array(int, T) [with T = double]
stack.cc:33: error: ‘def’ cannot appear in a constant-expression
stack.cc:33: error: template argument 1 is invalid
stack.cc:33: error: ‘def’ is not a type
stack.cc:33: error: invalid type in declaration before ‘;’ token
What's the best thing I can do here? Cuz I tried a lot of things to get rid of this error in line 31, but all attempts failed.
You are trying to construct a template using a variable name instead of a typename which you cannot do. It makes no sense. Also why are you creating a temporary array which would be destroyed immediately after the constructor finishes? Why do you think that _s would exist for the other functions? If it is a class attribute then you have a major problem with the design of the Stack class. Your Stack class looks like it also needs to be a template and its template type would have to be used for constructing _s. You should rework this and if you have more question post your declaration of Stack, array, and a main function that tries to use them so that we can fully understand what you are trying to do.
The compiler error is very informative. It says that in the constructor, you are attempting to create an Array<double> using its [non-existent] default constructor (line 33). Additionally, it continues to suggest that the template parameter (also on line 33) should not be 'def'. I think 'double' is what you are after. Then (still on line 33), there is a extra 'int'. You'll probably find that fixing the 'int' one will fix the first one, sometimes the errors are related.
However, this constructor is only creating a local Array, anyway; so line 33 could effectively be removed altogether. I suspect that in stack.hh, there is a member (maybe named _s?) that you are trying to initialize or assign to. Post stack.hh for advice.
//This is the main code for the Stack exercise
#include <iostream>
#include "stack.hh" //The Header file declares Stack
usingnamespace std;
int main() {
Stack s(5,0) ; //Stack is being referred to a s throughout the code
// Write doubles into Stack
int i ;
for (i=0 ; i<5 ; i++) {
cout << "pushing value " << i*100 << " in stack" << endl ;
s.push(i*100) ;
}
s.inspect();
// Count doubles in stack
cout << s.nitems() << " value in stack" << endl ;
/*
Stack sclone(s) ;
cout << "cloned stack after cloning" << endl;
sclone.inspect() ;
*/
// Read doubles back from stack
while (!s.empty()) {
double val = s.pop() ;
cout << "popping value " << val << " from stack" << endl ;
}
s.inspect();
return 0 ;
}
I use this program to practice with templates function. Later on I have to change the class stack into a template as well, but before that I want to check if this is working properly.
One of my problems is that I have still problems with the basics. At some points I have kinda an idea what my code is doing, but not exactly. So that may be the reason why I am doing weird or funny stuff on some places, just because I don't know any better.
Ok, so there is a member _s. So in the Stack constructor, there is no need to declare another Array<double>. Additionally, though, since Array does not have a default constructor you'll have to specify its constructor's arguments in the initialization list.
Try this on for size:
1 2 3 4
Stack::Stack(int length, double def)
: _s( length, def ) // this calls the constructor for _s, which is 'Array<T>::Array( int, T ) [with T = double]'
{
}
Without the initialization list, the Stack constructor attempts to default construct _s, until you [optionally] assign it a value later. Later could actually be quite soon--as soon as inside the {}'s of the constructor, for example!
never mind. I found the culprit of my problem. In my code I didn't set "count = 0" while calling the Stack constructor and therefore I get a problem in Stack::push _s[count++] = c. Count is set to nitems(), so doing _s[count++] I am trying to assign c to an element of my stack that has no allocated memory.