I'm currently doing an assignment for course and it involves creating a template class. I have the template class set up and everything, but I'm getting errors that I can't seem to fix. I have tried various solutions and neither have worked so far, I have also done a reasonable amount of research and found no answers, precisely relevant to my scenario, concerning the problem although many others have asked.
Here is the code thus far...
#ifndef STACK_H
#define STACK_H
#include "Queue.h"
#include "MyException.h"
#include <iostream>
using namespace std;
template<class T>
class Stack;
template<class T>
ostream& operator<<(ostream&,Stack<T>&);
template<class T>
class Stack
{
public:
Stack();
Stack(const Stack<T>& other);
void push(const T& el);
T pop();
T peek();
bool isEmpty();
friend ostream& operator<< <T>(ostream&,Stack<T>&);
Stack<T>& operator=(const Stack<T>& other);~Stack();
private:
class Node
{
public:
Node(const T& data, Node* n = 0)
{
element = data;
next = n;
}
T element;
Node* next;
};
Node* top;
};
#include "Stack.cpp"
#endif
that is the "Stack.h" and then there is
template<class T>
Stack<T>::Stack()
{
}
template <class T>
Stack<T>::Stack(const Stack<T>& other)
{
}
template <class T>
void Stack<T>::push(const T& el)
{
}
template <class T>
T Stack<T>::pop()
{
}
template <class T>
T Stack<T>::peek()
{
}
template <class T>
bool Stack<T>::isEmpty()
{
return false;
}
that is the "Stack.cpp".
I understand that the implementation being in a different file is not the generally accepted method, but unfortunately that is where the code needs to be. Now when I run this even without any real code, so to speak, i get the following errors.
3: expected constructor, destructor, or type conversion before '<' token
3: expected ';' before '<' token
9: expected constructor, destructor, or type conversion before '<' token
9: expected ';' before '<' token
17: expected init-declarator before '<' token
17: expected ';' before '<' token
23: expected init-declatator before '<' token
23: expected ';' before '<' token
and it goes on like that for each function up unto line 35.
Now, could it be my compiler? Could it be that I haven't finished all the functions and returned something yet?
Any help whatsoever would be largely appreciated, thanks.
Don't compile Stack.cpp in a separate translation unit; it is already included in Stack.h.
clang++ -c Stack.h -std=c++11
works just fine.
The problem is that you are suppose to include the .h file in your .cpp file. So remove the
#include "Stack.cpp"
That is at the bottom of your header file and add
#include "Stack.h"
to the top of your .cpp file.
Related
I am realizing a templated Stack structure on the base of vector in C++. I am not sure what is wrong with my code.
Stack.h
#ifndef STACK_H_
#define STACK_H_
#include <vector>
using namespace std;
template <class T>
class Stack {
public:
Stack();
virtual ~Stack();
bool empty();
int size();
void push(T pushvar);
T pop();
private:
std::vector<T> container;
};
#endif /* STACK_H_ */
Stack.cpp
#include "Stack.h"
#include <vector>
//template <class T>
Stack::Stack()
:container(0)
{
}
Stack::~Stack() {
// TODO Auto-generated destructor stub
}
bool Stack::empty(){
return (container.empty());
}
Even before calling anything from the main, Eclipse gives me several errors. But I will give an exemplary main:
#include <iostream>
#include "Stack.cpp"
using namespace std;
int main() {
Stack<int> s;
cout << s.empty();
return (0);
}
The compiler returns the following errors:
Description Resource Path Location Type
'container' was not declared in this scope Stack.cpp /PracticeCpp/src line 23 C/C++ Problem
'template<class T> class Stack' used without template parameters Stack.cpp /PracticeCpp/src line 22 C/C++ Problem
invalid use of template-name 'Stack' without an argument list Stack.cpp /PracticeCpp/src line 12 C/C++ Problem
invalid use of template-name 'Stack' without an argument list Stack.cpp /PracticeCpp/src line 18 C/C++ Problem
Member declaration not found Stack.cpp /PracticeCpp/src line 12 Semantic Error
Member declaration not found Stack.cpp /PracticeCpp/src line 18 Semantic Error
Member declaration not found Stack.cpp /PracticeCpp/src line 22 Semantic Error
Method 'empty' could not be resolved Stack.cpp /PracticeCpp/src line 23 Semantic Error
Symbol 'container' could not be resolved Stack.cpp /PracticeCpp/src line 13 Semantic Error
I know that I haven't realized all the methods declared in the header file, but this is not my problem. Before I continue realizing them I want to understand where am I wrong?
Correction after the answers:
I followed the suggestions in the answers but still I don't get what continues to be wrong. I moved the template realizations to the header. I deleted the other unrealized methods to avoid confusion. Now my .cpp file is empty.
My new header file:
#ifndef STACK_H_
#define STACK_H_
#include <vector>
template <class T>
class Stack {
private:
std::vector<T> container;
public:
template <typename T>
Stack<T>::Stack() : container(0)
{
}
template <class T>
bool Stack::empty() {
return container.empty();
}
};
#endif /* STACK_H_ */
definition should be
template <typename T>
Stack<T>::Stack() : container(0)
{
}
And not in .cpp
The method Stack::empty() was never declared, you declared Stack<T>::empty(). The same is true for each other constructor, operator and method. Add a template declaration to each implementation to fix this error. Notice that the error message hints at the mistake by saying "invalid use of template-name 'Stack' without an argument list".
Example :
template<class T> bool Stack<T>::empty() {
return container.empty();
}
Implementations for template methods should be included in header files. See this question.
Edit :
Regarding your newest example, you've mixed up two solutions. Try either :
#include <vector>
template <class T>
class Stack {
private:
std::vector<T> container;
public:
Stack() : container(0)
{
}
bool empty() {
return container.empty();
}
};
OR
#include <vector>
template <class T>
class Stack {
private:
std::vector<T> container;
public:
Stack();
bool empty();
};
template<class T>
Stack<T>::Stack() : container(0)
{
}
template<class T>
bool Stack<T>::empty()
{
return container.empty();
}
In the first solution, you are defining your functions within the definition of your class. The compiler knows that you are working on class Stack<T>, you mustn't remind it. In the second solution, the functions are defined outside the class. Here, you must specify which class' empty method and constructor you are defining.
This question already has an answer here:
Nested templates with dependent scope
(1 answer)
Closed 6 years ago.
having trouble when trying to compile a template class.
In the .h file
template <typename dataType>
class Node {
private:
dataType nodeData;
Node<dataType>* nextLink;
Node<dataType>* previousLink;
public:
Node(const dataType& nodeData);
// methods
In the .template file
template <typename dataType>
Node<dataType>::dataType Node<dataType>::getData() const {
return nodeData;
};
The error I get when trying to compile is:
need ‘typename’ before ‘Node<dataType>::dataType’ because ‘Node<dataType>’ is a dependent scope
Node<dataType>::dataType Node<dataType>::getData() const {
So then I add typename and it then gives me this error:
error: expected nested-name-specifier before ‘dataType’
typename dataType getData() const;
^
error: expected ‘;’ at end of member declaration
error: declaration of ‘int Node<dataType>::dataType’
error: shadows template parm ‘class dataType’
template <typename dataType>
^
What have I done wrong?
There is no member called dataType, I assume the return type should be just the template dataType:
template <typename dataType>
dataType Node<dataType>::getData() const {
return nodeData;
}
The compiler message is misleading in this case as it doesn't find proper definition, it assumes the dataType refers to the template argument.
template <typename DataType>
class Node {
public:
using dataType = DataType;
private:
dataType nodeData;
Node<dataType>* nextLink;
Node<dataType>* previousLink;
public:
Node(const dataType& nodeData);
dataType getData() const;
};
template <typename DataType>
typename Node<DataType>::dataType Node<DataType>::getData() const {
return nodeData;
};
specfy typename like this.
http://melpon.org/wandbox/permlink/Agu2s6vw6OLfbbRh
The presented example code is incomplete, so one would have to guess at the concrete problem.
However, here's how to do that class in a practical way, without problems like the one you're encountering:
template< class Item >
struct Node
{
Node* next;
Node* prev;
Item item;
};
Showing that it's sometimes possible to solve a problem without knowing the exact details.
I have two template classes, the first is:
template <typename T>
class LL_iterator
{...};
and :
template <class T>
class LL
{...}
Now, the issue is that I am trying to write a function declaration within the 'LL' class that has a 'LL_iterator' return type. The function inside of the 'LL' class looks like this:
LL_iterator<T> begin();
The errors I am receiving are the following:
Error 1 error C2143: syntax error : missing ';' before '<' c:\users\vismark1994\documents\visual studio 2013\projects\project 4\project 4\ll.h 103 1 Project 4
Error 2 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\users\vismark1994\documents\visual studio 2013\projects\project 4\project 4\ll.h 103 1 Project 4
Error 3 error C2238: unexpected token(s) preceding ';' c:\users\vismark1994\documents\visual studio 2013\projects\project 4\project 4\ll.h 103 1 Project 4
Error 4 error C1903: unable to recover from previous error(s); stopping compilation c:\users\vismark1994\documents\visual studio 2013\projects\project 4\project 4\ll.h 103 1 Project 4
Below are the complete class declarations:
template <class T>
class LL
{
private:
int count;
Node<T>* head;
Node<T>* tail;
void copyList(const LL<T> &listToCopy);
public:
LL();
LL(const LL<T> &otherLL);
~LL();
void push_back(T);
void push_front(T);
void pop_back();
void clear();
int size() const;
T& at(int ndx);
T& operator[] (int ndx);
T& at(int ndx) const;
T& operator[] (int ndx) const;
const LL& operator=(const LL<T> & rhsObj);
LL_iterator<T> begin(); // <-- this is where problem is
};
template <typename T>
class LL_iterator
{
private:
Node<T> *current;
public:
LL_iterator();
LL_iterator(Node<T> *ptr);
T& operator*();
LL_iterator operator++();
bool operator==(const LL_iterator &rhsObj) const;
bool operator!=(const LL_iterator &rhsObj) const;
}; //END class LL_iterator
I'm simply not sure how to write the function declaration for such a function (a function that returns a template type).
Thanks in advance!
You can declare a class template without defining it, just like you can with classes, functions and variables:
template <typename> class Bar;
template <typename T> class Foo
{
inline Bar<T> DoSomething(); // "inline" now has to be explicit
};
template <typename T> class Bar
{
Foo<T> DoAnotherThing() // implicitly "inline"
{
// implementation, may use Foo<T> as complete
}
};
template <typename T>
Bar<T> Foo<T>::DoSomething()
{
// implementation, now Bar<T> is complete, too
}
That way you can complete the definitions of mutually dependent class templates (since member function return and parameter types do not need to be complete at the point of declaration of the member function), and you can add member function definitions later.
You need to, at the very least, declare the LLIterator template before you define the LL class to be able to use it in the declaration of a member function. Where you first refer to LLIterator<T>, the name LLIterator is not known to the compiler.
Well, I've checked for missing semicolons, and to my knowledge I don't have any inclusion loops, so I'm kind of stumped. I've been looking at other examples posted and I still don't quite see what I'm missing. I'm going to guess it's something to do with the use of templates that I'm not dealing with right, but I really don't know.
In file included from customtester.cpp:6:0:
MyBSTree.h:23:1: error: expected class-name before â{â token
File:
#ifndef MYBSTREE_H
#define MYBSTREE_H
template <typename T> //not sure which of these I need,
class AbstractBSTree; //the include, the forward
#include "abstractbstree.h" //declaration, or both.
template <typename T>
class TreeNode
{
T m_data;
TreeNode<T> * m_right;
TreeNode<T> * m_left;
};
template <typename T>
class MyBSTree:public AbstractBSTree //this would be line 23
{
TreeNode<T> * m_root;
int m_size;
};
#endif
Anything I'm missing? I cannot modify "abstractbstree.h"
try:
public AbstractBSTree<T>
the compiler will assume the <T> only inside a template body and only for the templated class, not in public space
You're missing a <T>.
Since AbstractBSTree is a template class, you need to specify the template parameter when you derive from it for MyBSTree:
template <typename T>
class MyBSTree:public AbstractBSTree<T> // <-- Use <T> here
{
TreeNode<T> * m_root;
int m_size;
};
I'm trying to write an implementation of a 2-3-4 tree in c++. I'm it's been a while since I've used templates, and I'm getting some errors. Here's my extremely basic code framework:
node.h:
#ifndef TTFNODE_H
#define TTFNODE_H
template <class T>
class TreeNode
{
private:
TreeNode();
TreeNode(T item);
T data[3];
TreeNode<T>* child[4];
friend class TwoThreeFourTree<T>;
int nodeType;
};
#endif
node.cpp:
#include "node.h"
using namespace std;
template <class T>
//default constructor
TreeNode<T>::TreeNode(){
}
template <class T>
//paramerter receving constructor
TreeNode<T>::TreeNode(T item){
data[0] = item;
nodeType = 2;
}
TwoThreeFourTree.h
#include "node.h"
#ifndef TWO_H
#define TWO_H
enum result {same, leaf,lchild,lmchild,rmchild, rchild};
template <class T> class TwoThreeFourTree
{
public:
TwoThreeFourTree();
private:
TreeNode<T> * root;
};
#endif
TwoThreeFourTree.cpp:
#include "TwoThreeFourTree.h"
#include <iostream>
#include <string>
using namespace std;
template <class T>
TwoThreeFourTree<T>::TwoThreeFourTree(){
root = NULL;
}
And main.cpp:
#include "TwoThreeFourTree.h"
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
int main(){
ifstream inFile;
string filename = "numbers.txt";
inFile.open (filename.c_str());
int curInt = 0;
TwoThreeFourTree <TreeNode> Tree;
while(!inFile.eof()){
inFile >> curInt;
cout << curInt << " " << endl;
}
inFile.close();
}
And when I try to compile from the command line with:
g++ main.cpp node.cpp TwoThreeFourTree.cpp
I get the following errors:
In file included from TwoThreeFourTree.h:1,
from main.cpp:1:
node.h:12: error: ‘TwoThreeFourTree’ is not a template
main.cpp: In function ‘int main()’:
main.cpp:13: error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> class TwoThreeFourTree’
main.cpp:13: error: expected a type, got ‘TreeNode’
main.cpp:13: error: invalid type in declaration before ‘;’ token
In file included from node.cpp:1:
node.h:12: error: ‘TwoThreeFourTree’ is not a template
In file included from TwoThreeFourTree.h:1,
from TwoThreeFourTree.cpp:1:
node.h:12: error: ‘TwoThreeFourTree’ is not a template
My main question is why it's saying "error: ‘TwoThreeFourTree’ is not a template". Does anyone have any ideas? Thanks for all advice/help in advance...
Dan
The solution that has been accepted has the slight problem of opening your class to any instantiation of the TwoThreeFourTree template, not only those that share the same instantiation type.
If you only want to open the class to instantiations of the same type you can use the following syntax:
template <typename T> class TwoThreeFourTree; // forward declare the other template
template <typename T>
class TreeNode {
friend class TwoThreeFourTree<T>;
// ...
};
template <typename T>
class TwoThreeFourTree {
// ...
};
You just need to declare it as a template when you use the friend keyword. You're using incorrect syntax for a friend declaration in your code. What you want to write is:
template <class U> friend class TwoThreeFourTree;