C++ Linked Lists Template Class - c++

I'm currently practicing some linked list assignments out of my book right now and I'm stuck compiling errors. The implementation file seems to be fine, however the header file is what is receiving the errors.
Here is my header file:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <string>
using namespace std;
template<class T>
class linkedList {
public:
linkedList();
linkedList(const linkedList& copy);
~linkedList();
int getSize() const;
void addEntry(T entry);
bool deleteEntry(T entry);
T getEntry(int input) const;
linkedList operator=(const linkedList& right);
private:
struct node {
T data;
node<T> *next;
};
node<T> *linkedList = NULL;
};
#include "linkedlist.cpp"
#endif // LINKEDLIST_H
The errors I'm getting from my compiler is as follows:
c:\users\andym_000\documents\linkedlist\linkedlist.h(22) : error C2059: syntax error : '<'
c:\users\andym_000\documents\linkedlist\linkedlist.h(20) : see reference to class template instantiation 'linkedList<T>::node' being compiled
c:\users\andym_000\documents\linkedlist\linkedlist.h(25) : see reference to class template instantiation 'linkedList<T>' being compiled
c:\users\andym_000\documents\linkedlist\linkedlist.h(22) : error C2238: unexpected token(s) preceding ';'
c:\users\andym_000\documents\linkedlist\linkedlist.h(24) : error C2059: syntax error : '<'
c:\users\andym_000\documents\linkedlist\linkedlist.h(24) : error C2238: unexpected token(s) preceding ';'
c:\users\andym_000\documents\linkedlist\linkedList.h(24) : error C2059: syntax error : '<'
..\linkedList\main.cpp(9) : see reference to class template instantiation 'linkedList<T>' being compiled
with
[
T=std::string
]
c:\users\andym_000\documents\linkedlist\linkedList.h(24) : error C2238: unexpected token(s) preceding ';'
c:\users\andym_000\documents\linkedlist\linkedList.h(24) : error C2059: syntax error : '<'
..\linkedList\main.cpp(10) : see reference to class template instantiation 'linkedList<T>' being compiled
with
[
T=int
]
c:\users\andym_000\documents\linkedlist\linkedList.h(24) : error C2238: unexpected token(s) preceding ';'

Um, struct node {...} isn't a template. Your errors are telling you that is has no idea what to do with node<T>.

You use template notation with node class, which s not a template. T type is defined for whole linkedList - in definiition of node it is well defined type.
Note that node is defined inside linkedList, so it's qualified name will be linkedList<T>::node for linkedList<T> (i.e. each instantiation of linkedList has it's own node class).
So, just replace node<T> with node and that should work.

Related

When adding the header file in the .cpp file, errors arise

The Nodes.h file alone when compiled works, however when I include it in the Nodes.cpp file, all the errors arise, such as missing type specifier - int assumed at line 11,12,13 . Also another error is syntax error: identifier 'ASTSimpleExpressionNode'. Is it something that I am doing wrong. Can't I specify how my struct can be constructed by defining the different constructors?
For now the ASTSimpleExpressionNode is empty because if I continued the process it would duplicate all the errors.
Some of the errors:
Error C2535 'ASTExpressionNode::ASTExpressionNode(void)': member
function already defined or declared [line 16] Error C4430 missing
type specifier - int assumed. Note: C++ does not support
default-int [Line 11, 12,13 so on.] Error C2143 syntax error: missing
';' before '*' [Line 11,12,13] unexpected token(s) preceding ';' [Line
11,12,13]
Nodes.h file.
#pragma once
#include <string>
using namespace std;
struct ASTNode
{
};
struct ASTExpressionNode : ASTNode
{
ASTSimpleExpressionNode *left;
ASTRelationOperatorNode *rel_op;
ASTSimpleExpressionNode *right;
ASTExpressionNode(ASTSimpleExpressionNode *l);
ASTExpressionNode(ASTSimpleExpressionNode *l, ASTRelationOperatorNode *op, ASTSimpleExpressionNode *r);
};
struct ASTSimpleExpressionNode : ASTExpressionNode
{
};
struct ASTRelationOperatorNode :ASTExpressionNode
{
string rel_op;
ASTRelationOperatorNode(string op);
};
Nodes.cpp file.
#include "Nodes.h"
Forward-declare ASTSimpleExpressionNode and ASTRelationOperatorNode:
struct ASTSimpleExpressionNode;
struct ASTRelationOperatorNode;
struct ASTExpressionNode : ASTNode
{
// etc

Very Confused on Template INL File

Okay, I thought I had implementation files for template classes figured out, but apparently not... I have the following files in a VS 2013 C++ solution:
Main.cpp
#include "StateManager.h"
#include "State.h"
enum class Derp {
Herp,
Lerp,
Sherp,
};
int main() {
Game2D::State<Derp>::Context context(5);
Game2D::StateManager<Derp> mgr(context);
return 0;
}
StateManager.h
#pragma once
#include "State.h"
namespace Game2D {
template<typename Id>
class StateManager {
private:
typename State<Id>::Context _context;
public:
explicit StateManager(typename State<Id>::Context context);
};
#include "StateManager.inl"
}
StateManager.inl
template<typename Id>
StateManager<Id>::StateManager(typename State<Id>::Context context) :
_context(context)
{ }
State.h
#pragma once
namespace Game2D {
template<typename Id>
class StateManager;
template<typename Id>
class State {
public:
struct Context {
Context(int);
int data;
};
private:
StateManager<Id>* _manager;
Context _context;
public:
State(StateManager<Id>&, Context);
virtual ~State();
};
#include "State.inl"
}
State.inl
template<typename Id>
State<Id>::Context::Context(int data) {
this->data = data;
}
template<typename Id>
State<Id>::State(StateManager<Id>& manager, Context context) :
_manager(&manager),
_context(context)
{ }
template<typename Id>
State<Id>::~State() { }
Building this Project yields the following errors:
Error 10 error C1903: unable to recover from previous error(s); stopping compilation state.inl 9 1
Error 9 error C2065: 'context' : undeclared identifier state.inl 8 1
Error 7 error C2065: 'manager' : undeclared identifier state.inl 7 1
Error 8 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int state.inl 7 1
Error 6 error C2039: 'State' : is not a member of '`global namespace'' state.inl 6 1
Error 1 error C2143: syntax error : missing ';' before '<' state.inl 2 1
Error 2 error C2988: unrecognizable template declaration/definition state.inl 2 1
Error 3 error C2059: syntax error : '<' state.inl 2 1
Error 4 error C3083: 'Context': the symbol to the left of a '::' must be a type state.inl 2 1
Error 5 error C2039: 'Context' : is not a member of '`global namespace'' state.inl 2 1
Any help on how to fix these errors would be much appreciated!
A wild guess would be that you added your .inl files to you your project as standalone translation units and the compiler attempted to compile them as standalone translation units.
These files make no sense as standalone translation units and they will not compile as such. These are include files (aka header files). They are supposed to be seen as header files by the project. They are not supposed to be compiled directly.

symbol cannot be used in a using-declaration

I've got a header in which my base problem is with the using keyword.
#ifndef SHAPEFACTORY_H__
#define SHAPEFACTORY_H__
#include <istream>
#include <map>
#include <string>
#include "shape.h"
/* thrown when a shape cannot be read from a stream */
template<class T>
class WrongFormatException { };
template<class T>
class ShapeFactory
{
public:
using createShapeFunction=Shape<T>*()(void);
static void registerFunction(const std::string &, const createShapeFunction *);
static Shape<T> *createShape(const std::string &);
static Shape<T> *createShape(std::istream &);
private:
std::map<std::string, createShapeFunction *> creationFunctions;
ShapeFactory();
static ShapeFactory<T> *getShapeFactory();
};
#endif
And I've got some errors which I can't resolve.
1>shapefactory.h(21): error C2873: 'createShapeFunction' : symbol cannot be used in a using-declaration
1>shapefactory.h(29) : see reference to class template instantiation 'ShapeFactory<T>' being compiled
1>shapefactory.h(21): error C2143: syntax error : missing ';' before '='
1>shapefactory.h(21): error C2238: unexpected token(s) preceding ';'
1>shapefactory.h(22): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>shapefactory.h(22): error C2143: syntax error : missing ',' before '*'
1>shapefactory.h(26): error C2065: 'createShapeFunction' : undeclared identifier
1>shapefactory.h(26): error C2059: syntax error : '>'
1>shapefactory.h(29): error C2143: syntax error : missing ';' before '}'
1>shapefactory.h(29): fatal error C1004: unexpected end-of-file found
Any idea would be great.
It seems that the compiler does not support the alias decladation. Substitute it for a typedef declaration. For example (at least the code is compiled)
#include <map>
#include <string>
template <typename T>
class Shape;
template<class T>
class ShapeFactory
{
public:
typedef Shape<T>* createShapeFunction(void);
static void registerFunction(const std::string &, const createShapeFunction *);
static Shape<T> *createShape(const std::string &);
static Shape<T> *createShape(std::istream &);
private:
std::map<std::string, createShapeFunction *> creationFunctions;
ShapeFactory();
static ShapeFactory<T> *getShapeFactory();
};
int main()
{
return 0;
}

Trying to compile a .h file without understanding something

I'm trying to compile Opengazer (Open source gaze tracker) code with visual studio on windows, while the code was originally written for linux and should be compile with cmake.
Anyway, I can't compile few files.
The code won't compile is this:
Containers.h:
#pragma once
#define xforeachactive(iter,container) \
for(typeof(container.begin()) iter = container.begin(); \
iter != container.end(); iter++) \
if ((*iter)->parent == this)
template <class ParentType, class ChildType> class Container;
template <class ParentType, class ChildType>
class Containee {
protected:
void detach() { parent = 0; }
public:
ParentType *parent; /* set to null to request removal */
Containee(): parent(0) {}
virtual ~Containee() {}
};
template <class ParentType, class ChildType>
class Container {
typedef ChildType *ChildPtr;
static bool isFinished(const ChildPtr &object) {
return !(object && object->parent);
}
protected:
std::vector<ChildPtr> objects;
void removeFinished() {
objects.erase(remove_if(objects.begin(), objects.end(), isFinished),
objects.end());
}
public:
void clear() {
xforeachactive(iter, objects)
(*iter)->parent = 0;
removeFinished();
}
static void addchild(ParentType *parent, const ChildPtr &child) {
parent->objects.push_back(child);
child->parent = parent;
parent->removeFinished();
}
virtual ~Container() {
clear();
}
};
template <class ParentPtr, class ChildPtr>
class ProcessContainer: public Container<ParentPtr, ChildPtr> {
public:
virtual void process() {
xforeachactive(iter, this->objects)
(*iter)->process();
this->removeFinished();
}
virtual ~ProcessContainer() {};
};
btw Containers.cpp is empty
ad the code uses the above class is:
#pragma once
class FrameProcessing;
class FrameFunction:
public Containee<FrameProcessing, FrameFunction>
{
const int &frameno;
int startframe;
protected:
int getFrame() { return frameno - startframe; }
public:
FrameFunction(const int &frameno): frameno(frameno), startframe(frameno) {}
virtual void process()=0;
virtual ~FrameFunction();
};
class FrameProcessing:
public ProcessContainer<FrameProcessing,FrameFunction> {};
class MovingTarget: public FrameFunction {
WindowPointer *pointer;
public:
MovingTarget(const int &frameno,
const vector<Point>& points,
WindowPointer *&pointer,
int dwelltime=20);
virtual ~MovingTarget();
virtual void process();
protected:
vector<Point> points;
const int dwelltime;
int getPointNo();
int getPointFrame();
bool active();
};
class CalibrationHandler
{
public:
CalibrationHandler(void);
~CalibrationHandler(void);
};
the error I get is :
visual studio 2008\projects\eyemouse\eyemouse\containers.h(58) : error C2146: syntax error : missing ';' before identifier 'iter'
visual studio 2008\projects\eyemouse\eyemouse\containers.h(58) : error C2065: 'iter' : undeclared identifier
visual studio 2008\projects\eyemouse\eyemouse\containers.h(58) : error C2065: 'iter' : undeclared identifier
visual studio 2008\projects\eyemouse\eyemouse\containers.h(58) : error C2146: syntax error : missing ')' before identifier 'iter'
visual studio 2008\projects\eyemouse\eyemouse\containers.h(58) : error C2059: syntax error : ';'
visual studio 2008\projects\eyemouse\eyemouse\containers.h(58) : error C2065: 'iter' : undeclared identifier
visual studio 2008\projects\eyemouse\eyemouse\containers.h(58) : error C2059: syntax error : ')'
visual studio 2008\projects\eyemouse\eyemouse\containers.h(58) : error C2143: syntax error : missing ';' before 'if'
visual studio 2008\projects\eyemouse\eyemouse\containers.h(58) : error C2065: 'iter' : undeclared identifier
visual studio 2008\projects\eyemouse\eyemouse\containers.h(58) : error C2227: left of '->parent' must point to class/struct/union/generic type
type is ''unknown-type''
visual studio 2008\projects\eyemouse\eyemouse\containers.h(59) : error C2065: 'iter' : undeclared identifier
visual studio 2008\projects\eyemouse\eyemouse\containers.h(59) : error C2227: left of '->process' must point to class/struct/union/generic type
type is ''unknown-type''
I understand why I'm getting an error.
'iter' is not defined anywhere. anyway, this isnt my code and it should work.
I tried to copy and past the define part to the function, but still get the same error.
I'm stuck with this and trying to solve it for hours, but can't understand what to do to make it work.
I'll really be grateful for any help.
typeof is a gcc extension and equivalent to C++0x decltype there is no VS version that actually supports it.
You would need to use C++0x and decltype or try to use Boost.TypeOf, which comes with its own caveats.
Change the macro to this:
#include <boost/typeof/typeof.hpp>
#define xforeachactive(iter,container) \
for(BOOST_TYPEOF(container.begin()) iter = container.begin(); \
iter != container.end(); iter++) \
if ((*iter)->parent == this)
You could also use BOOST_AUTO if you think this is clearer.

C++ template and pointers

I have a problem with a template and pointers ( I think ). Below is the part of my code:
/* ItemCollection.h */
#ifndef ITEMCOLLECTION_H
#define ITEMCOLLECTION_H
#include <cstddef>
using namespace std;
template <class T> class ItemCollection
{
public:
// constructor
//destructor
void insertItem( const T );
private:
struct Item
{
T price;
Item* left;
Item* right;
};
Item* root;
Item* insert( T, Item* );
};
#endif
And the file with function defintion:
/* ItemCollectionTemp.h-member functions defintion */
#include <iostream>
#include <cstddef>
#include "ItemCollection.h"
template <class T>
Item* ItemCollection <T>::insert( T p, Item* ptr)
{
// function body
}
Here are the errors which are generated by this line of code:
Item* ItemCollection <T>::insert( T p, Item* ptr)
Errors:
error C2143: syntax error : missing ';' before '*'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2065: 'Type' : undeclared identifier
error C2065: 'Type' : undeclared identifier
error C2146: syntax error : missing ')' before identifier 'p'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2470: 'ItemCollection::insert' : looks like a function definition, but there is no parameter list; skipping apparent body
error C2072: 'ItemCollection::insert': initialization of a function
error C2059: syntax error : ')'
Any help is much appreciated.
The short answer is what Alexey already posted:
template <typename T>
typename ItemCollection<T>::Item* ItemCollection<T>::insert( T p, Item * ptr ) {
// ...
}
(To understand why typename is required, search SO for related questions, or else drop a comment. I will focus the answer in the lookup rules that explain why the return and the argument types must be declared differently)
The explanation is that the lookup rules in c++ have different scopes for the return type and the rest of the parameters. When the compiler sees the definition A B::c( D ), A is checked in the enclosing namespace of the definition, as is B. When the compiler finds ::c it looks up c inside class B. At that point, the rest of the definition is inside the scope of the class B for the rest of parameters. That means that if the return type is an internal type of the class, you have to use the qualified name for the return type, while in the case of D the compiler will first look it up inside the class B.
That explains why the return type must be fully qualified even if the last parameter is not. When the parameter Item * ptr is found by the compiler, it is already in the scope of the class, and it will find it there. On the other hand, there is no Item defined in the enclosing namespace.
One of the changes in the upcomming standard will deal with this, even if it was not designed with this purpose in mind. If I recall correctly, the following syntax should compile without the full type qualification:
template <T>
auto ItemCollection<T>::insert( T p, Item * ptr ) -> Item *
{
return 0;
}
The reason is exactly the same. After ItemCollection<T>::insert has been parsed the remainder tokens will be verified inside the ItemCollection<T> scope, including the -> Item * return definition.
template <class T>
typename ItemCollection <T>::Item* ItemCollection<T>::insert( T p, Item* ptr)
{
// function body
}