I don't understand what is wrong with this code.
gcc reports "Client.h:29: error: expected template-name before '<' token"
As far as I'm aware I'm followed the template syntax correctly, but it could be that the error message is confusing me and is not the problem
client.h
class Client : public BaseDll<DllClient> [line 29]
{
..snip..
};
basedll.h
template<typename T>
class BaseDll : public Base
{
public:
..snip..
private:
T* _dll;
};
class Base{
};
template<typename T>
class BaseDll:public Base{
public:
private:
T* _dll;
};
class DllClient{
};
class Clien:public BaseDll<DllClient>
{
};
this compiled for me without problems, so I don't think the problem lies within what you posted. My best bet would be that you made a syntax error in client.h, maybe something as simple as forgetting a semicolon after another class definition or some macro that's messing with your code
I'm so sorry everyone, a school-boy error has been made, BaseDll is declared in another namespace. As soon as I added the namespace qualifier, the problem has gone.
Maybe it's just an easy problem: Have you included basedll.h in client.h?
to cover the basics:
does client-h #include basedll.h? do they user different include guards?
Further troubleshooting:
does it work with a non-template base class?
does it work then you typedef the template instaltiation:
typedef BaseDll<DllClient> tClientBase;
class Client : public tClientBase { ... }
[edit] OK, next:
if you put the following two lines directly under the BaseDll declaration:
template <typename T>
class BaseDll
{ ...
};
class DummyFoo;
typedef BaseDll<DummyFoo> tDummyFoo;
I think you snipped away the problem. Are you including something to define 'DllClient' ?
A possible cause of this is that there is an inter-dependency between the different header files:
// client.h
#ifndef CLIENT
#define CLIENT
#include "base.h"
// ...
class Client : public BaseDll<DllClient>
{
// ..snip..
};
#endif
// base.h
#ifndef BASE
#define BASE
#include "client.h"
template<typename T>
class BaseDll : public Base
{
public:
// ..snip..
private:
T* _dll;
};
#endif
Now imagine we're parsing 'base.cpp' then the preprocessor will do the following:
#include "base.h"
#ifndef BASE <--- BASE unset, keep going
#define BASE
#include "client.h"
#ifndef CLIENT
#define CLIENT
#include "base.h"
#ifndef BASE <--- BASE set, skip base.h, return to client.h
class client
: public BaseDll<DllClient> <-- ERROR, BaseDll not defined.
If this is the problem, then you potentially can get around it by forward declaring the base template in client.h:
// client.h
#ifndef CLIENT
#define CLIENT
// #include "base.h" <-- remove include
template <typename DLL_CLIENT>
class BaseDll;
// ...
class Client : public BaseDll<DllClient>
{
// ..snip..
};
#endif
Related
I have templated MyDatabase class and two derived classes Database_A and Database_B. I have another class C which is using Database_A and Database_B. So, whenever I am including headers of both derived class (Database_A and Database_B) in class C, it gives me this error "Redefinition of MyDatabase". My guessing is, because both derived class (Database_A and Database_B) are dragging template class MyDatabase, it could be the reason for redefinition of MyDatabase. But I don't know how to resolve this problem.
My code:
template <typename U, class T> class My_DataBase {
protected:
std::map<U,T> Container
public:
void add();
T* getNameToPointer(string key);
};
class Database_A: public My_Database <string,A> {
add();
A* getNameToPointer(name);
};
class Database_B: public My_DataBase <string,B> {
add();
B* getNameToPointer(name);
};
class C {
private:
Database_A Db_A; // drage template class on back_end
Database_B Db_B; // drage template class on back_end
};
How can I solve this problem?
It seems like you have two header files, where each header file contains the base class and a dereived class. That's why you get a redefinition error.
To avoid this issue do this: Use three header files and include guards. The base class will be in one header file, named "My_DataBase.h". The two other headers files (one for every dereived class) will include "My_DataBase.h".
However, since you may want to include both header files (of the derived classes), you need to make use of the include guards to avoid redefinition of the base class.
So here is an example:
My_DataBase.h
#ifndef MY_DATABASE_H
#define MY_DATABASE_H
template <typename U, class T> class My_DataBase {
protected:
std::map<U,T> Container
public:
void add();
T* getNameToPointer(string key);
}
#endif
Database_A.h
#ifndef DATABASE_A_H
#define DATABASE_A_H
#include "My_DataBase.h"
class Database_A: public My_Database <string,A> {
add();
A* getNameToPointer(name);
}
Database_B.h
#ifndef DATABASE_B_H
#define DATABASE_B_H
#include "My_DataBase.h"
class Database_B:public My_DataBase <string,B> {
add();
B* getNameToPointer(name);
}
You should prevent header files from multiple inclusion.
You can do this either by specifiying #pragma once instruction on the top of your header files (however I think this is Microsoft specific).
A better way is to surround your header file by code similar to the following :
#ifndef MYHEADER_FILENAME
#define MYHEADER_FILENAME
/// whatever contained in your header file
...
#endif // MYHEADER_FILENAME
following situation:
I have in one dll a template class Point
namespace Image
{
template<typename T> class Point
{
.
.
.
and tring to use this class in another dll. The class looks like:
//Base.h
template<typename T> class Point;
class Base{
Point<double> _Point;
};
//Child.h
#include "Base.h"
class Child : public Base{
Child(Point<double> pt);
doSth();
}
//Child.cpp
#include "Child.h"
#include "Point.h"
Child::Child(Point<double> pt){
_Point = pt;
}
Child::dosth(){
Point<double> p = _Point; // In this Row i get an "undefined type 'Point<double>' Error
}
Any ideas why i get the error?
is my idea totally wrong to forward declare the Point-Class in the header file and make the include in the .cpp ?
Thank you very much, have a nice day!
With the forward declaration you have in Base.h it doesn't matter if you used using namespace Image; first, the template class you declare in Base.h is still in the global namespace and not in the Image namespace. And that declaration will take precedence over the one in the Image namespace.
So there are really two solutions here: Either explicitly use Image::Point, or remove the forward declaration in Base.h (and include the header file where Image::Point<> is defined).
#ifndef CLASSB
#define CLASSB
#include "ClassA.h"
namespace name {
class ClassB
{
public:
static Handle conn();
};
}
#endif
-
#include "ClassB.h"
Handle name::ClassB::conn()
{
return getHandle(ClassA::it().str());
}
-
#ifndef CLASSA
#define CLASSA
#include "ClassB.h"
namespace name {
class ClassA
{
public:
template <typename T>
T myFunc(const std::string&)
{
auto tmp = ClassB::conn();
}
};
}
#endif
Calling ClassB::conn() gives a compiler error which says that the class ClassB is not declared. When I forward declare it I get an error message about an incomplete type.
I can't move the template function to my .cpp files as it is a template function. So, how to fix this?
Just remove #include "ClassA.h" from class B's header and it should work. But there appear to be multiple compilation problems with your code so it's hard to say (missing function getHandle, missing it(), missing type Handle etc).
I am trying to implement a generic hashlist class using templates and I am trying to inherit from the base class but getting lots of compile errors. Here is my code:
#ifndef BASEHASHLIST_H_
#define BASEHASHLIST_H_
#include <string>
#include <boost/unordered_set.hpp>
#include <iostream>
#include <boost/interprocess/sync/interprocess_semaphore.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
template <typename T>
class BaseHashList
{
private:
boost::interprocess::interprocess_semaphore m_semaphore;
protected:
boost::unordered_set<T> m_hsHashSet;
typename boost::unordered_set<T>::iterator m_hsIter;
public:
BaseHashList();
};
template <typename T>
BaseHashList<T>::BaseHashList():m_semaphore(1){}
#endif /* BASEHASHLIST_H_ */
And here is the class that is inheriting from the base class:
#ifndef ACCOUNTLIST_H_
#define ACCOUNTLIST_H_
#include "BaseHashList.h"
class AccountList : public BaseHashList<unsigned long>
{
public:
AccountList(std::string p_strFile, unsigned long p_ulMaxAccountNo);
~AccountList(void);
int m_iVersion;
std::string m_strFilePath;
private:
unsigned long m_ulMaxAccountNo;
};
#endif /* ACCOUNTLIST_H_ */
and here is the cpp file:
#include "AccountList.h"
AccountList::AccountList(std::string p_strFile, unsigned long p_ulMaxAccountNo)
: BaseHashList<unsigned long>::m_hsHashSet<unsigned long>(),
m_iVersion(0),
m_strFilePath(p_strFile)
{
m_ulMaxAccountNo = p_ulMaxAccountNo;
}
AccountList::~AccountList(){}
I am receiving a lot of compile time errors such as:
expected template-name before token '<'
expected '(' before token '<'
For such a simple task I spent couple of hours and I am super frustrated, does anybody see what I am doing wrong here?
This initaliser in AccountList's constructor looks wrong to me:
BaseHashList<unsigned long>::m_hsHashSet<unsigned long>()
You should initalise the members of BaseHashList inside a constructor of BaseHashList itself, one will always either explicitly or implicitly be called.
This example is simplified and similarly wrong:
struct A {
int bar;
};
struct B : A {
B() : A::bar(0) {}
};
(saying bar(0) would also be wrong there)
However you can get the desired behaviour:
struct A {
A() : bar(0) {}
int bar;
};
struct B : A {
B() {} // Implicitly calls A::A although we could have explicitly called it
};
The constructor of A gets called and given a chance to initalise its members here still.
When you inherit from a template class, you have to add the template instruction to the child class too :
template <typename T>
class A : public B<T>
You also have to add the template instruction before the definition of constructors and methods :
template <typename T>
A<T>::A() : B<T>() {...}
template <typename T>
A<T>::~A() {...}
I am trying to implement an observer pattern with a template subject class. The observers don't (need to) know the subjects type, so I made an interface for the attach method without this type. This is my implementation:
SubjectInterface.h
#ifndef SUBJECTINTERFACE_H_
#define SUBJECTINTERFACE_H_
#include <list>
#include "Observer.h"
// Template-independant interface for registering observers
class SubjectInterface
{
public:
virtual void Attach(Observer*) = 0;
}; // class SubjectInterface
#endif // SUBJECTINTERFACE_H_
Subject.h
#ifndef SUBJECT_H_
#define SUBJECT_H_
#include <list>
#include "Observer.h"
#include "SubjectInterface.h"
template <class T>
class Subject : public SubjectInterface
{
public:
Subject();
~Subject();
void Attach(Observer*);
private:
T mValue;
std::list<Observer*> mObservers;
}; // class Subject
#include "Subject.cpp"
#endif // SUBJECT_H_
Subject.cpp
template <class T>
Subject<T>::Subject()
{
}
template <class T>
Subject<T>::~Subject()
{
}
template <class T>
void Subject<T>::Attach(Observer* test)
{
mObservers.push_back(test);
}
Observer.h
#ifndef OBSERVER_H_
#define OBSERVER_H_
#include "SubjectInterface.h"
#include <iostream>
class Observer
{
public:
Observer(SubjectInterface* Master);
virtual ~Observer();
private:
SubjectInterface* mMaster;
}; // class Observer
#endif // OBSERVER_H_
Observer.cpp
#include "Observer.h" // include header file
Observer::Observer(SubjectInterface* Master)
{
Master->Attach(this);
}
Observer::~Observer()
{
}
When I compile this using the gcc 4.3.4, I get the following error message:
SubjectInterface.h:10: error: ‘Observer’ has not been declared
I don't understand this, because the Observer is included just a few lines above. When I change the pointer type from Observer* to int*, it compiles OK. I assume that there is a problem with the template subject and the non-template interface to it, but that is not what gcc is telling me and that doesn't seem to be the problem when using int*.
I searched for template/observer, but what I found (e.g. Implementing a Subject/Observer pattern with templates) is not quite what I need.
Can anyone tell me, what I did wrong or how I can call the templated attach-method from a non-template observer?
You have a circular include chain, SubjectInterface.h includes Observer.h which in turns includes SubjectInterface.h.
This means that the include guards will prevent Observer from being visible. To fix it instead forward declare Observer.
// SubjectInterface.h
#ifndef SUBJECTINTERFACE_H_
#define SUBJECTINTERFACE_H_
#include <list>
class Observer; //Forward declaration
// Template-independant interface for registering observers
class SubjectInterface
{
public:
virtual void Attach(Observer*) = 0;
}; // class SubjectInterface
#endif // SUBJECTINTERFACE_H_
You have a circular dependency; Observer.h includes SubjectInterface.h, and vice versa. You will need to break this with a forward declaration.