I am trying to pass a pointer to a function that then sets a unique_ptr inside a struct to the pointer passed in. However, I get the following compile error on the last line of the function.
error C2280: 'std::unique_ptr< ALLEGRO_BITMAP,std::default_delete< ALLEGRO_BITMAP>>::unique_ptr(const std::unique_ptr< ALLEGRO_BITMAP,std::default_delete< ALLEGRO_BITMAP>> &)' : attempting to reference a deleted function
c:\program files (x86)\microsoft visual studio 12.0\vc\include\memory(1486) : see declaration of 'std::unique_ptr< ALLEGRO_BITMAP,std::default_delete< ALLEGRO_BITMAP>>::unique_ptr'
This diagnostic occurred in the compiler generated function 'Skin::Skin(const Skin &)'
Judging from the errors I believe it has something to do with me adding the delete template for ALLEGRO_BITMAP to namespace std, but I don't know why or how to fix it.
using namespace std;
namespace std {
template<>
class default_delete < ALLEGRO_BITMAP > {
public:
void operator()(ALLEGRO_BITMAP* ptr) {
al_destroy_bitmap(ptr);
}
};
}
typedef struct {
unique_ptr<ALLEGRO_BITMAP> img;
} Skin;
typedef struct {
Skin skins[MAX_ENTITY_COUNT];
} World;
unsigned int createBlock(World world, ALLEGRO_BITMAP* img) {
unsigned int entity = newEntityIndex(world);
world.skins[entity].img = make_unique<ALLEGRO_BITMAP>(img);
return entity;
} // error on this line
Any help is appreciated. Thanks.
In your createBlock function you take World by value which means that it will be copied. However, you can't copy a unique_ptr so that is where your error comes from. This would also mean that setting the unqiue_ptr in the function wouldn't have any effect.
Instead you should take World by reference:
unsigned int createBlock(World& world, ALLEGRO_BITMAP* img) {
unsigned int entity = newEntityIndex(world);
world.skins[entity].img = make_unique<ALLEGRO_BITMAP>(img);
return entity;
}
Note that the same is true for the call to newEntityIndex and that the arguments to make_unique will be passed to the ALLEGRO_BITMAP constructor.
So what you probably want is:
world.skins[entity].img.reset(img);
Related
Here is the code:
#include <iostream>
using namespace std;
template<class OwnerType>
class Move {
public:
Move() {}
Move(OwnerType &_owner) {
owner = &_owner;
}
void GetPosition() {
cout << owner->x << endl;
}
OwnerType *owner;
};
class Entity {
public:
int x = 50;
Move<Entity> *move;
};
int main() {
Entity en;
en.x = 77;
en.move = new Move<Entity>(en); // sign '=' is underlined by VS
en.move->GetPosition();
return 0;
}
Error it gives :
a value of type "Move<Entity> *" cannot be assigned to an entity of type "Move<Entity> *"
The program is compiling, working as expected and gives expected values, however error is still here.
It's probably something to do with templates and compiling time and stuff but I don't have enough knowledge to know what this error actually represents.
Also don't worry about leaks since this was just me testing, error is what I don't understand.
Thanks in advance.
Intellisense is known for displaying invalid errors (see for example Visual Studio 2015: Intellisense errors but solution compiles), trust the compiler and linker, as suggested in comments.
However, this error is quite annoying, try closing the solution, delete the .suo file (it's hidden), and open in again. More info on what a .suo file is given here Solution User Options (.Suo) File
Side note, in your code example main is missing ().
so it is not Error.
it is Intellisense :
see:
Error 'a value of type "X *" cannot be assigned to an entity of type "X *"' when using typedef struct
Visual Studio 2015: Intellisense errors but solution compiles
old:
your main needs ():
this works for me:
#include<iostream>
using namespace std;
template<class T> class Move {
public:
Move() {}
Move(T &_owner) {
owner = &_owner;
}
void GetPosition() {
cout << owner->x << endl;
}
T *owner;
};
class Entity {
public:
int x = 50;
Move<Entity> *move;
};
int main(){
Entity en;
en.x = 77;
en.move = new Move<Entity>(en); // sign '=' is underlined by VS
en.move->GetPosition();
return 0;
}
output:
77
Here is my code:
// WorkDamnit.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
class Scheduler
{
public:
typedef void (*function_ptr) (void);
struct Task
{
function_ptr function;
int numOfTasks;
};
void Init(Task *tasks, int numOfTasks);
private:
int _numOfTasks;
Task *_tasks;
};
void Scheduler::Init(Scheduler::Task *tasks, int numOfTasks)
{
_tasks = tasks;
_numOfTasks = numOfTasks;
}
void count() {};
Scheduler::Task task_list =
{
count, 1
};
Scheduler scheduler;
Scheduler.Init(Scheduler::Task &task_list,1);
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
I get the following errors from the compiler:
1>c:\users\evan\documents\visual studio 2012\projects\workdamnit\workdamnit\workdamnit.cpp(49): error C2143: syntax error : missing ';' before '.'
1>c:\users\evan\documents\visual studio 2012\projects\workdamnit\workdamnit\workdamnit.cpp(49): error C2059: syntax error : '.'
The compiler doesnt seem to like the line after the class object definition. When i try to call the init() member. All i can think of is that it has to do with the pointer to function reference. Maybe someone can shed some light on this for me?
You can call call functions/methods directly outside of other methods/functions.
Scheduler.Init(Scheduler::Task &task_list,1);
2 problems in this line.
The above seems to be outside of any function/method. For eg. you can put in inside main.
The line itself is not correct. So change it to
scheduler.Init(&task_list,1);
Usually you call a method on an object not a class name, except for static methods. You don't pass the parameter type while passing parameters to the method.
So the changed line in main will look like
int _tmain(int argc, _TCHAR* argv[])
{
scheduler.Init(&task_list,1);
return 0;
}
Line 49 should be:
scheduler.Init(Scheduler::Task &task_list,1); // note the lowercase 's': the object should be used, not the class
Also it should be within a function (maybe main in your case)
I am facing an error in one of my projects which I have replicated using a standalone program. I did see several posts pertinent to this, but could not figure out my problem. I am getting the following error with this code : "error: expected constructor, destructor, or type conversion before '&' token"
#include <iostream>
#include <boost/shared_ptr.hpp>
using namespace std;
class X
{
private:
int _x;
public:
X(int x) : _x(x) {};
};
class Y
{
private:
typedef boost::shared_ptr<X> X_ptr;
public:
X_ptr& func1();
};
X_ptr& Y::func1()
{
X_ptr p(new X(8));
return p;
};
int main()
{
return 0;
}
Can someon help me with in resolving this error?
There are two problems. First, you forgot to qualify the type name X_ptr:
Y::X_ptr& Y::func1()
// ^^^ ^
// BUT REMOVE THIS!
Second, notice that you are returning a reference to a local variable. Attempting to dereference the value returned by func1() will give you undefined behavior.
Just change the prototype of your function this way:
Y::X_ptr Y::func1()
// ^^^^^
// Returning the smart pointer by value now
{
X_ptr p(new X(8));
return p;
}
I am trying to implement the a map from the C++ STL as follows:
#include <string>
#include <iostream>
#include <map>
using namespace std;
#include "assembler.h"
// This Class makes use of the Map Template from the Standart Template Library
// All addresses are stored as numerical (Dec) integers
SymbolTable::SymbolTable() { // Constructor
map <string, int> symbolTable;
int address = 0;
}
void SymbolTable::addEntry(string symbol, int address) {
symbolTable[symbol] = address;
address++;
}
// Returns true if symbolTable already contains symbol
bool SymbolTable::contains(string symbol) {
if (symbolTable.find(symbol) == symbolTable.end()) { return true; }
else { return false; }
}
int SymbolTable::getAddress(string symbol) {
return symbolTable[symbol];
}
I try to compile this with
c++ *.cpp -0 assembler.out
and I get the following error message:
symboltable.cpp:57:9: error: no viable conversion from 'mapped_type' (aka 'std::basic_string<char>') to 'int'
return symbolTable[symbol];
^~~~~~~~~~~~~~~~~~~
1 error generated.
I have searched for this error online and all I get is bug reports relating to the STL and I cannot figure out if those reports are the same problem I am having and if so how to get around it. Am I doing something wrong?
I have tried (probably stupidly) to typecast the offending line as
return (int) symbolTable[symbol];
Thank you for any help.
My header file declares the class as:
class SymbolTable {
public:
SymbolTable();
void addEntry(string, int);
bool contains(string);
int getAddress(string);
private:
map <string, string> symbolTable;
int address;
};
This:
SymbolTable::SymbolTable() { // Constructor
map <string, int> symbolTable;
^
^
is a function-local variable, not a member variable. It is not the same as the symbolTable that you're accessing in e.g. getAddress, which presumably is a member variable. You haven't shown the class body, but my guess is that it's defined differently.
My goal is to create a system wherein I can provide the string name of an class at run time and have it return an instance of that class in turn.
Searching stackoverflow, I came across an example that seems to do exactly what I am trying to accomplish, although I am currently unable to have it compile properly. The following is based on that code:
//LevelObject.h
#pragma once
#include <map>
#include <string>
class LevelObject
{
protected:
int ID;
public:
template<class T> static LevelObject* createT(void)
{
return new T(0);
}
LevelObject(void);
~LevelObject(void);
};
struct BaseFactory
{
typedef std::map<std::string, LevelObject*(*)()> map_type;
static LevelObject* createInstance(const std::string& s)
{
map_type::iterator it = getMap()->find(s);
if(it == getMap()->end())
{
return 0;
}
return it->second();
}
private:
static map_type* objectMap;
protected:
static map_type* getMap()
{
if(!objectMap)
{
objectMap= new map_type;
}
return objectMap;
}
};
template<class T>
struct DerivedRegister : BaseFactory
{
DerivedRegister(const std::string& s)
{
getMap()->insert(std::make_pair( s, &LevelObject::createT<T> ));
}
};
//Item.h
#pragma once
#include "LevelObject.h"
class Item :
public LevelObject
{
int ID;
static DerivedRegister<Item> reg;
public:
Item(int id);
~Item(void);
};
//Item.cpp
#include "Item.h"
Item::Item(int id)
{
ID = id;
}
Item::~Item(void)
{
}
DerivedRegister<Item> Item::reg("item");
The logic is that the derived objects, i.e. Item, will register a string and reference to a function that returns an instance of itself. On calling createInstance, it will take in a user inputted string and use the map to determine the object to return.
Unfortunately, this code is not compiling correctly, and gives me the following errors:
Error 1 error C2752:
'std::tr1::_Remove_reference<_Ty>' :
more than one partial specialization
matches the template argument list
Error 2 error C2528: 'abstract
declarator' : pointer to reference is
illegal c:\program files\microsoft
visual studio
10.0\vc\include\type_traits 965
Error 3 error C2528: 'type' : pointer
to reference is illegal c:\program
files\microsoft visual studio
10.0\vc\include\type_traits 349
If someone can help smooth out these errors, I would greatly appreciate it.
Or perhaps I am going about this entirely wrong in the first place, so if someone instead feels that I should be going in a different direction entirely please let me know.
Thanks in advance.
It's been a long time since this question was posted, but since there's no answer and I stumbled here too, I figured I'd add one. I copied the same factory code you did (from the StackOverflow answer here) and had the same problem. I found the solution at this StackOverflow answer.
It turns out Visual Studio 2010 (which I'm assuming you're using) has a problem with std::make_pair. Just use std::pair<std::string,LevelObject*(*)()> instead and you'll be good to go. At least that resolved this exact same problem for me.
I added empty bodies to the LevelObject class constructor and destructor:
LevelObject(void) { }
~LevelObject(void) { }
Then declared the static map member variable of the BaeFactory class:
BaseFactory::map_type* BaseFactory::map;
and the code compiled without errors in both GCC and Visual Studio.