I am working on a project that requires a list(singly) of stacks. I have made a class called "stacklist" that is just that, a list of stacks. I want the class to have a stack pointer that will point to the head of the list. However, I keep getting an error whenever I try to build the class.
#ifndef STACKLIST_H
#define STACKLIST_H
#include <stack>
//source: Data Structures Using C++: Linked List Implementation Part II (List Class)
//url: http://www.youtube.com/watch?feature=endscreen&NR=1&v=7vZo17iv1zQ
class stacklist
{
public:
stacklist();
void addToHead(const int&);
void printList();
void insert(const int&);
private:
stack<int>* head; //THIS IS WHERE I AM HAVING THE PROBLEM
int size;
};
#endif // STACKLIST_H
The error message is "error: expected ';' before '<' token"
Any insight that can be provided would be highly appreciated.
The standard library stack lives in the std namespace, so you need to qualify the name appropriately:
std::stack<int>* head;
You should consider using an std::list<std::stack<int>> instead of your class.
The correct name of the template is std::stack.
If all you want is a list of stacks, you could always use std::list<std::stack<int>>, by the way (or std::forward_list if you only need forward traversal). But even if you pursued your own design, there's probably no reason why you can't make the stack a direct class member.
Perhaps you should say std::stack
std::stack<int>* head; instead stack<int>* head;
If you're using std libraries, you must put std:: before the std object or place a using namespace std at the beggining of your source file:
#include <stack>
using namespace std; // This line brings std stuff into the current namespace.
Or:
std::stack<int>* head;
If your file is a header, it's better the first one than the second one because the using directive will be spreaded into all the files that includes StackList.h
This is no mentioned on the question, but I think is worth to say: Is quite dangerous to use pointers into classes, because you must take care of it into all constructors (default and copy) and take care on destructor too.
Revise your class dessign and think if you can use a std::stack instance instead of std::stack pointer.
Related
I have problem with define syntax of List this error that I getting, I tried creating a list of Vertice and I have problem with the syntax, I tried using namespace STD also in a header but still getting an error:
Severity Code Description Project File Line Suppression State
Error (active) E0415 no suitable constructor exists to convert from "std::list> *" to "std::list>" graf C:\Users\danie\OneDrive\Desktop\graf\graf\Vertice.cpp 39
Vertice.h
#pragma once
#include <list>
#include <iostream>
class Vertice {
std::list<Vertice> getList();
void setList(Vertice v);
private:
std::list<Vertice> *N;
};
Vertice.cpp
#pragma once
#include <list>
#include <iostream>
#include "Vertice.h"
using namespace std;
Vertice::Vertice(int b, int f) {
N = new list < Vertice > ();
color = 0;
}
list < Vertice > Vertice::getList() {
return N;
}
void Vertice::setList(Vertice v) {
this - > N - > push_front(v);
}
Vertice::~Vertice() {
N - > clear();
}
The reason why you are getting comments and not answers is because you
a) Did not post the error message (as mentioned in a comment)
b) Your code contains many errors and some anti-patterns.
When using namespaces in C++ the convention is to use the full namespace in header
std::list<Vertice> *N; // member declaration
and a "using" declaration in the module.
using namespace std;
...
list<Vertice> Vertice::getList() const // return by value, mark as const
{
return N; // you don't need this->N in C++
}
However, many people prefer to simply type the full namespace always, so if you find this easier to understand, try using that.
What are you trying to achieve with this code? The reason I ask is because dynamically allocating a "std::list" is a bit weird. A "std::list" is designed to manage memory for you, which makes this code read a bit like "allocate a pointer to hold the address of the memory I'm about to allocate". I strongly suspect you are trying to make a recursive structure (a tree). Surprisingly C++ does not require you to use pointers to do this (C does). Maybe this pattern will help?
class NTree
{
private:
std::list<NTree> children;
};
I would suggest you get your code working like that first. If need to optimize, you will more control of the memory, then something like this will help.
class NTree
{
private:
std::vector<std::unique_ptr<NTree>> children;
};
This will allow you to, for example, move a child from one node (NTree) to another (NTree - or other), in a safe way. This avoids any copying overhead. This is a minor saving unless either your trees get very big or they contain objects which are very big. Even expert C++ programmers will try and get their code working before trying an optimization like this. There is no way to predict if it will required or not, so as always benchmark before and after.
Although I've searched, I don't know if this is possible at all.
How can I prevent a library user from writing using namespace myns; anywhere in his/her code?
Let's say I implemented a library that encloses all its elements in a namespace called myns:
namespace myns
{
class MyClass
{
};
class string
{
};
}
This library will be used by another programmer. How can I force him/her to use
// somewhere in code
myns::MyClass myClass;
myns::string myString;
std::string stdString;
instead of
using namespace myns;
// somewhere in code
MyClass myClass;
string myString; // this would most likely be a mess
string stdString;
This would help with namespace collisions.
You can't. The standard says one can write using namespace myns; to get all the names, and there is nothing you can do about that.
If the user gets collisions after using namespace XXX;, that's their own fault. Generally, it is not possible to stop people from shooting themselves in the foot if they try to.
In the end, pulling in all names from some third party namespace is not something that happens on accident, but has been discouraged since about the dawn of time. If the user decides to do it anyways, they better know what they are doing. Really not the problem of the library maintainer.
One (questionable) workaround I can think of is replacing your namespace with a class or a struct of the same name and turning everything in your namespace into a (static) member of this class.
struct myns final
{
class MyClass
{
}
class string
{
}
private:
// private constructor, copy constructor and assignment operator
// ...
};
This would preclude programmers, using your library from writing using namespace myns but... well, like I said, I consider such a workaround to be quite questionable.
Note that users will still be able to use type aliases, such as:
using string = myns::string;
I just finished creating my binary tree class only to realise that I was supposed to make it as a template. I've spent hours now trying to get to convert it to a template, but I keep getting a multitude of errors ranging from "invalid use of template-name" to "extra qualification of a member". I am new to the concept of templates but I have an idea of what I'm trying to achieve.
BTree.cpp
#include <iostream>
#include <string>
#include "BTree.h"
using namespace std;
BTree::BTree(board startboard, string startplayer)
{
treeboard = startboard;
player = startplayer;
root = new BTNode(treeboard, player,-1,-1);
}
BTree::~BTree()
{
delete root;
}
int BTree::sumtree()
{
if (root->getvalue(-1) > root->getvalue(1))
return root->getchildposition(-1);
else
return root->getchildposition(1);
}
BTree.h
#include <string>
#include "BTNode.h"
#include "board.h"
using namespace std;
class BTree
{
public:
BTree(board startboard, string startplayer);
~BTree();
int sumtree();
private:
string player;
board treeboard;
BTNode *root;
};
'startplayer' is currently a string, I would like this to be the generic template type.
What should my process be for turning this into a single template file?
Well, let's first look what errors or other deficits your code has:
Your BTree has a custom dtor, because it holds resources. But you are violating the rule-of-3:
You need to define or delete, at minimum, your assignment-operator and copy-ctor.
As an alternative (preferable), change BTNode *root; to use std::unique_ptr.
The first thing included in the implementation-file should always be its own header, to find broken dependencies in the header.
The header should include everything neccessary to use it, and not one bit more.
Now, there are good reasons why templates are usually header-only:
The compiler needs the definition to instantiate it.
Use the opportunity to move some of the functions into the class.
Next, you define a template like this:
template<class T> class BTree {
int BTree::sumtree();
};
And non-inline members like this:
template<class T> int BTree<T>::sumtree() {
return //...
}
In the template, you can use the type-argument like a normal type.
A note on BTNode: It's an implementation-detail of BTree, so put its definition into the class (which makes templating it the same and using it easier as well.)
Alternatively, if you don't actually need all the template-arguments for BTNode as well (or want to share its implementation), template it separately.
Don't forget to change all references from BTree though.
First of all to use templates in C++ all of your executable code NEEDS to be in the .h file so it is available at compile time.
Then to template your class, the usual way is to make it like :
template<class T>
class BTree
{
Btree(T startPlayer)
{
player = startPlayer;
}
// ... snip ...
T player;
}
I am relatively new to c++ and am having a heck of a time getting my main program to instantiate my class. I am used to java so I'm not sure if I am mixing up the two languages as I attempt to do this and that is my problem or maybe I just don't understand the concept correctly.
The object of my program: The object of this program is to create a template class from an interface that will make a sorted array that you can add and remove items from it while keeping it sorted.
Note: Please help me actually understand this process as to just telling me the exact code to use because I really want to understand what I am doing wrong for next time.
Step 1: I created my sorted interface:
sortedInterface.h
#ifndef _SORTED_INTERFACE
#define _SORTED_INTERFACE
#include <vector>
using namespace std;
template<class ListItemType>
class sortedInterface
{
public:
virtual bool sortedIsEmpty();
virtual int sortedGetLength();
virtual bool sortedInsert(ListItemType newItem);
virtual bool sortedRemove(ListItemType anItem);
virtual bool sortedRetrieve(int index, ListItemType dataItem);
virtual int locatePosition(ListItemType anItem);
}; // end SortedInterface
#endif
then I used the interface to create the sorted.h file:
sorted.h
#include "sortedInterface.h"
#include <iostream>
#ifndef SORTED_H
#define SORTED_H
using namespace std;
template<class ListItemType>
class sorted
{
public:
sorted();
sorted(int i);
bool sortedIsEmpty();
int sortedGetLength();
bool sortedInsert(ListItemType newItem);
bool sortedRemove(ListItemType anItem);
bool sortedRetrieve(int index, ListItemType dataItem);
int locatePosition(ListItemType anItem);
protected:
private:
const int DEFAULT_BAG_SIZE = 10;
ListItemType items[];
int itemCount;
int maxItems;
};
#endif // SORTED_H
and finally I created the sorted.cpp (I only included the constructor for now as I can't even get that working)
#include "sorted.h"
#include <iostream>
using namespace std;
template<class ListItemType>
sorted<ListItemType>::sorted()
{
itemCount = 0;
items[DEFAULT_BAG_SIZE];
maxItems = DEFAULT_BAG_SIZE;
}
My main program:
#include "sortedInterface.h"
#include "sorted.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
sorted<string> sorted1 = new sorted();
return 0;
};
Any help is appreciated in explaining where my logic is failing on this and any hints on how to properly execute my task. Thanks!
1) operator "new" returns a pointer, not an object.
sorted<string>* sorted1 = new sorted<string>();
2) However, in your small example, there is no need to create sorted1 using "new".
sorted<string> sorted1;
One word of advice -- Java is not C++. You made the two mistakes that many first-time Java programmers make when writing C++ code, namely 1) believing that to create an object, you must use "new", and 2), that "new" returns a reference.
There are a few things wrong with your interface/implementation. A class template is usually implemented entirely in the header in which it's declared; this is because the compiler creates a whole new type for each type you use with your template.
Second, in your sortedInterface template, you've made the members virtual which still requires a definition, but you do not supply one. You can mark your member functions with = 0; to make them all pure virtual, which means the classes that inherit your sortedInterface will have to implement those members instead.
Third, as PaulMcKenzie pointed out, operator new() returns a pointer to a heap-allocated object, but you're expecting a value type.
Finally, please take a look at smart pointers if you're using naked new()s everywhere.
I notice the following additional anomalies in the entire implementation:
An interface is something which should be non-instantiable but it is
instantiable in your case (because there is not even a single pure
virtual function in your so called interface) Standard rule is to
make all the functions in the interface pure virtual (=0)
class Sorted does not inherit from the so-called interface
sortedInterface
You have not defined all versions of your constructor in your class
Sorted
If you want the polymorphism to work (Interface to Concrete), you
need to have virtual class destructors in both the interface and
concrete class
I am developing a list in which I have used some protected variables count, entry[maxlist] etc.
List.h
class List
{
public:
//etc etc
protected:
int count;
int entry[maxlist];
};
Sortable_list.h
typedef Key Record;
class Sortable_list:public List<Record>
{
void selection_sort()
{
for(int position=count-1;position>0;i--) // Count is not declared in the scope
{
int max=max_key(0, position);
swap(max, position);
}
}
};
Is something wrong with inheriting the List to Sortable List? Why is it showing count out of scope?
#Edit: After seeing your whole code it becomes clearer. You're having ambiguities because of your includes, it will compile with msvc, because it handles such cases silently, but for g++ you should explicitly state that count is from this class, by doing this->count. You also had problems because of std::range_error, which could be avoided by removing using namespace std or replacing range_error with ::range_error which will indicate that you want the global scope. Another problem with your code is that, you were using an undefined variable i in your Sortable_list. The fixed code that compiles with g++ and msvc: http://codepad.org/7V70rNqf
I don't want to sound rude, but I strongly suggest you read a book on C++, your current code is very anti-idiomatic, and could be made generic with a smaller amount of code.
Why don't you use sort function template from <algorithm> header? All you need to write just one small Compare function.
Look like your List is not a template class, so List< Typename > doesn't exist ..
Also, you can use std::set<T> as a template class for sorted container => http://www.sgi.com/tech/stl/set.html