"class template has already been declared as a non-class template" - c++

Hey i'm getting this odd error when I leave the namespace sf{ declaration in the later code:
1>c:\libraries and headers\sfml\sfml-1.6-sdk-windows-vc2008\sfml-1.6\include\sfml\graphics\body.h(70): error C2989: 'sf::Body' : class template has already been declared as a non-class template
1>c:\libraries and headers\sfml\sfml-1.6-sdk-windows-vc2008\sfml-1.6\include\sfml\graphics\body.h(11): error C3856: 'sf': class is not a class template
The code worked fine when it wasn't a template class for the past 3 weeks, With the same sf::Body class name; i just recently changed it to make it more flexible. Can i not declare a template class inside a namespace or what?
Here's the code:
#include <SFML/Graphics.hpp>
#include <vector>
#include <math.h>
#include <cmath>
namespace sf{ //when i take this out and the closing bracket the code runs fine
template<typename drawable>
class Body : public sf::Drawable{
private:
sf::Vector2f MoveVal;
std::vector<drawable> Drawables;
public:
Body(const Vector2f& Position = Vector2f(0, 0), const Vector2f& Scale = Vector2f(1, 1), float Rotation = 0.f, const Color& Col = Color(255, 255, 255, 255)){
SetPosition(Position);
SetScale(Scale);
SetRotation(Rotation);
SetColor(Col);};
// Overide Drawable Functions To Detect any Movement
void SetX(float X){
MoveVal.x += X - GetPosition().x;
Drawable::SetX(X);};
void SetY(float Y){
MoveVal.y += Y - GetPosition().y;
Drawable::SetY(Y);};
// Regular Functions
void AddObject(drawable& Object){
Object.Move(GetX(),GetY());
Drawables.push_back(Object);};
void DestroyObject(unsigned short Index){
Drawables.erase(Drawables.begin()+Index);};
void Clear(){
Drawables.clear();};
drawable& GetObject(unsigned short index)
{return Drawables[index];};
unsigned int GetNumbObjects()
{return Drawables.size();};
void Draw(sf::RenderTarget& target){
for(unsigned short I=0; I<Drawables.size(); I++){
//Body offset
Drawables[I].SetPosition(
Drawables[I].GetPosition().x + MoveVal.x,
Drawables[I].GetPosition().y + MoveVal.y);
} // TODO: add tint based on overall Body Color
target.Draw(*this);
//Reset all the Change Values
MoveVal.x=0;
MoveVal.y=0;
};
void Render(sf::RenderTarget& target) const{
for(int I=0; I< Drawables.size(); I++)
Drawables[I].Draw(target);
};
};// Body Class
} //namespace sf

Ok found the problem:
In a previously included header file: Shape.hpp I declare Body as a friend with the following syntax:
friend class Body;
Which apparently makes the compiler assume Body is not a template (no template indication is made)
The correct syntax was:
template <typename drawable>
friend class Body;
Because now the compiler understands Body as a template class

The two most likely candidates based on your information are that Graphics.hpp has mismatched { } or that you had a forward declaration of class Body without marking it a template.

sf::Body is a name that seems to be already taken (for a class whereas you're declaring a template). Are you sure you want to put your code in the sf namespace? It's more customary to use one's own namespaces rather than those of the libraries they use.

Related

class put in a seperate cpp and .h files, it gives error undefined reference when built and when compiled warning function used but never defined [duplicate]

This question already has answers here:
Separating class code into a header and cpp file
(8 answers)
Closed 4 months ago.
fyi I have looked at the other posts on this topic but I either didn't understand or didn't find my problem in them.
pretty much I am trying to put a class into a cpp and .h file, when I compile the code I get a warning saying "warning: inline function 'float map::get_mapped_value()' used but never defined.
And when I build the code I get an error saying undefined reference to 'map::get_mapped_value'
below are the code in each file
I thought I had all my includes correct, but maybe I am missing something, I am new to separating classes into seperate file, so any help would be greatly appreciated.
Thanks in advance, Dean.
map.cpp
#include "map.hpp"
#include <stdio.h>
#include <iostream>
using namespace std;
//------------------------Constructor definitions--------------------------
map::map(float Val_to_map_, float in_min_, float in_max_, float out_min_, float out_max_)
: Val_to_map(Val_to_map_)
, in_min(in_min_)
, in_max(in_max_)
, out_min(out_min_)
, out_max(out_max_)
{
}
//-------------------------------------------------------------------------
//------------------------Copy Constructor definitions---------------------
map::map(const map& mp)
: Val_to_map(mp.Val_to_map)
, in_min(mp.in_min)
, in_max(mp.in_max)
, out_min(mp.out_min)
, out_max(mp.out_max)
{
}
//-------------------------------------------------------------------------
//-----------------------equals function-------------------------------------
map& map::operator=(const map& mp)
{
if(this == &mp)
return (*this);
Val_to_map = mp.Val_to_map;
in_min = mp.in_min;
in_max = mp.in_max;
out_min = mp.out_min;
out_max = mp.out_max;
return (*this);
}
//---------------------------------------------------------------------------
//-------------------get function definitions--------------
inline float map::get_mapped_value()
{
return (float((Val_to_map - in_min) * (out_max - out_min) / (in_max - in_min) + out_min));
}
//-----------------------------------------------------------
//-------------------set function definitions----------------
inline void map::set_Val_to_map(float _Val_to_map)
{
Val_to_map = _Val_to_map;
}
inline void map::set_in_min(float _in_min)
{
in_min = _in_min;
}
inline void map::set_in_max(float _in_max)
{
in_max = _in_max;
}
inline void map::set_out_min(float _out_min)
{
out_min = _out_min;
}
inline void map::set_out_max(float _out_max)
{
out_max = _out_max;
}
//-----------------------------------------------------------
map.h
#ifndef MAP_HPP
#define MAP_HPP
using namespace std;
class map
{
public:
//----------------Special Member functions-----------------
map(float Val_to_map_, float in_min_, float in_max_, float out_min_, float out_max_); // accepted arguments
map(const map& m); // copy constructor
map& operator=(const map& m); // Equals function
~map()
{
} // destructor
//---------------------------------------------------------
//-----------------get functions-----------------
inline float get_mapped_value();
//------------------------------------------------
//-----------------set functions-----------------
inline void set_Val_to_map(float Val_to_map);
inline void set_in_min(float in_min);
inline void set_in_max(float in_max);
inline void set_out_min(float out_min);
inline void set_out_max(float out_max);
//------------------------------------------------
private:
float Val_to_map;
float in_min; // min Vref
float in_max; // max Vref
float out_min; // min output voltage from psu
float out_max; // max output voltage from psu
};
#endif // MAP_HPP
main.cpp
main(){
map voltage(1, map_in_min, map_in_max, map_out_min, map_out_max);
cout << "Mapped val: " << voltage.get_mapped_value() << endl;
}
You declared the function get_mapped_value as an inline function
inline float get_mapped_value();
So its definition shall be in each compilation unit where it is used.
The simplest way to resolve the problem is to include the function definition either directly in the class definition where it is declared or in the header where the class definition is present.

Incomplete/Undefined type when using nested classes

I have been attempting to make some code, but I am a bit new to c++ and need some help.
I cannot instantiate class Player as a pointer, because it's an "incomplete type" (or undefined type, vs says both). Below are some (simplified, albeit not very) versions of my code:
Entity.h
#pragma once
#include <vector>
class Entity
{
public:
static void init();
class EntityObject;
class Player;
static std::vector<EntityObject*> entities;
};
Entity.cpp
#include "Entity.h"
void Entity::init()
{
entities = std::vector<EntityObject*>();
}
class Entity::EntityObject
{
private:
float velX, velY, x, y;
public:
EntityObject(float xa, float ya) { x = xa; y = ya; }
float getVelX() { return velX; }
float getVelY() { return velY; }
float getX() { return x; }
float getY() { return y; }
};
class Entity::Player : EntityObject
{
public:
Player(float xa, float ya) : EntityObject(xa, ya)
{
printf("Player created");
}
};
Can anyone tell me why
#include "Entity.h"
int main(int argc, char* argv)
{
Entity::init();
Entity::EntityObject* player = new Entity::Player(10.0f, 10.0f);
Entity::entities.push_back(player);
}
gives an incomplete/undefined type?
Thanks.
Edit:
The errors are:
Both errors direct to this line: Entity::EntityObject* player = new Entity::Player(10.0f, 10.0f);
Error (active) E0070 incomplete type is not allowed
Error C2027 use of undefined type 'Entity::Player'
You defined the Entity::Player class in the .cpp file, not in the .h file. Therefore, even though the main() includes the .h file, it does not know about Entity::Player.
Entity::Player is forward declared in Entity.h.
When the compiler compiles your main.cpp module, it does not know anything about this class except that it exists, in particular it has no idea that this class as a constructor taking two float : Player(float xa, float ya)
=> Your issue is related to forward declaring, not nested class.
Read this thread to understand your problem
What are forward declarations in C++?
Read this one to understand what you can and what you can't do with forward declaration
When can I use a forward declaration?

Arranging template related code in different headers

The code below works as long as I keep it all in the "main.cpp" file.
//#include "Travel.h"
//#include "Obj.h"
// "Travel.h"
typedef int travel_t;
class Travel
{
public:
static const travel_t AIR;
static const travel_t WATER;
static const travel_t LAND;
};
// "Travel.cpp"
// #ifndef TRAVEL_H
// #define TRAVEL_H
//
// #include "Travel.h"
const travel_t Travel::AIR = -2;
const travel_t Travel::WATER = -1;
const travel_t Travel::LAND = 0;
// #endif //TRAVEL_H
// "Obj.h"
// #ifndef OBJ_H
// #define OBJ_H
//
//#include "Travel.h"
template<typename T, travel_t travel>
class Obj
{
public:
void foo(){};
};
// #endif //OBJ_H
// "main.cpp"
int main()
{
Obj<int, Travel::AIR> objAirTravel;
objAirTravel.foo();
return 0;
}
However, as soon as I moved code to different headers and implementation files as indicated, it doesn't compile any more. :-( How can I fix that problem? What is the problem/rule behind it? This is the compiler error I get (using gcc):
main.cpp|45|error: 'Travel::AIR' is not a valid template argument for type 'int' because it is a non-constant expression|
main.cpp|45|error: invalid type in declaration before ';' token|
main.cpp|47|error: request for member 'foo' in 'objAirTravel', which is of non-class type 'int'|
In order to use a constant as a template argument, its value must be available in the current translation unit. When you move the definition of Travel::Air to a different source file, its value is no longer available to the compiler in main.
Since it's an integer constant, you can declare the value in the declaration inside the class:
class Travel
{
public:
static const travel_t AIR = -2;
static const travel_t WATER = -1;
static const travel_t LAND = 0;
};
Now the values are available to use as template arguments in any translation unit that includes this class definition.

What is wrong with this forward declaration

Several times I used the pimple idiom to get a short compilation time. To get a "good" header file I return a pointer of a vector that contains pointer of QPoint (an Qt-object).
Lets have a look at my header file:
#ifndef CHEXAGON_H
#define CHEXAGON_H
class QPoint;
class QVector;
class CHexagon
{
public:
CHexagon(const unsigned int & PosX, const unsigned int & PosY, const unsigned int & Radius);
QVector * getEdges();
QPoint * getCenter();
private:
class Pimple;
Pimple * pPimple;
};
#endif // CHEXAGON_H
Whats wrong with it?
QVector isn't a class, it is a class template and can't be declared as you did.
template <typename T> QVector;
and then using QVector<QPoint*> should do what you want.
Nothing.
What makes you think that something is wrong with it?

Is there anything wrong with the way that this C++ header is laid out?

#pragma once
#include "LudoCore/Singleton.h"
class LudoTimer : public Singleton<LudoTimer>
{
friend class Singleton<LudoTimer>;
public:
void Update();
void ShortenDay();
void LengthenDay();
UINT64 GetDeltaTime() const;
float GetPercentageOfDayElapsed() const;
private:
LudoTimer();
~LudoTimer();
UINT64 GetTickCount64() const;
UINT64 GetElapsedSeconds() const;
UINT64 m_DeltaTime;
// Tick Count
UINT64 m_CurrFrameTick;
UINT64 m_LastFrameTick;
int m_SecondsInADay;
static const int SHORTEST_POSSIBLE_DAY = 60;
static const int LONGEST_POSSIBLE_DAY = 86400;
static const int CHANGING_INTERVAL = 600;
};
To me, the above code looks normal. However, I'm new to C++ so I may be missing some nuance. I'm getting a bunch of compiler errors from it, such as:
error C2447: '{' : missing function header (old-style formal list?)
and
error C2236: unexpected 'class'
'LudoTimer'. Did you forget a ';'?
What gives!
Have a look in the other header (LudoCore/Singleton.h). The second error implies that the error is before the class LudoTimer declaration at the top.
My guess is that Singleton.h defines a class, and there's a missing ';' after that class definition.
The error is probably in LudoCore/Singleton.h or something else included earlier. Make sure your class definitions have ; semicolons after them and all that.
Quick test: comment out the #include and stick a template<class C> class Singleton; predeclaration there instead. If the compiler now complains about incomplete types, I'm right, and if not, post more details.
Well, the following compiles fine for me, so the error is very likely not in the code you showed us. I suggest you have a second look at Mike's suggestion that there is an error in Singleton.h.
//#include "LudoCore/Singleton.h"
#include <windows.h>
template< typename T >
class Singleton {};
class LudoTimer : public Singleton<LudoTimer>
{
friend class Singleton<LudoTimer>;
public:
void Update();
void ShortenDay();
void LengthenDay();
UINT64 GetDeltaTime() const;
float GetPercentageOfDayElapsed() const;
private:
LudoTimer();
~LudoTimer();
UINT64 GetTickCount64() const;
UINT64 GetElapsedSeconds() const;
UINT64 m_DeltaTime;
// Tick Count
UINT64 m_CurrFrameTick;
UINT64 m_LastFrameTick;
int m_SecondsInADay;
static const int SHORTEST_POSSIBLE_DAY = 60;
static const int LONGEST_POSSIBLE_DAY = 86400;
static const int CHANGING_INTERVAL = 600;
};
I was wondering if LudoTimer is declared at the point that it is used by Singleton and if a forward declaration would help? I didn't need one in VisualStudio 2005 and like sbi I could compile the code by supplying a declaration of Singleton. If I added a simplistic implementation I could even do:
LudoTimer* timer = Singleton<LudoTimer>::instance();
One more thing:
error C2236: unexpected 'class' 'LudoTimer'. Did you forget a ';'?
You could try adding a semicolon on a blank line after the #include to answer this question. If it helps then you can show that there is a problem in the header file without needing to edit it.