Constructing a std::thread from a class member function [duplicate] - c++

This question already has answers here:
Start thread with member function
(5 answers)
Closed 4 years ago.
I want to construct updateThread with updateWorldLoop() in World::World()
Chunk.h
class World
{
public:
static constexpr Chunk::Position renderSize = 10;
World();
//render chunks
void draw();
void drawDebug();
void enableUpdateThread();
void disableUpdateThread();
void updateWorldLoop();
private:
std::thread updateThread;
bool updateThreadShouldClose;
std::list<Chunk*> *frontDrawBuffer;
std::list<Chunk*> *backDrawBuffer;
std::list<Chunk*> unloadBuffer;
void loadChunk(Chunk::PosVec position);
};
Chunk.cpp
World::World() :
frontDrawBuffer(new std::list<Chunk*>),
backDrawBuffer(new std::list<Chunk*>),
unloadBuffer(),
updateThread(updateWorldLoop)
//ERROR: non-standard syntax; use '&' to create a pointer to member
{ /*Initialize textures*/}
I did some research and tried several ways. None of them worked.
updateThread(&updateWorldLoop);
//ERROR: '&': illegal operation on bound member function expression
updateThread(this->updateWorldLoop);
//ERROR: non-standard syntax; use '&' to create a pointer to member
updateThread(&this->updateWorldLoop);
//ERROR: '&': illegal operation on bound member function expression
updateThread(World::updateWorldLoop);
//ERROR: non-standard syntax; use '&' to create a pointer to member
updateThread(&World::updateWorldLoop);
/***ERROR:
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\thr\xthread(240): error C2672: 'std::invoke': no matching overloaded function found
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\thr\xthread(248): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Execute<0>(std::tuple<void (__cdecl World::* )(void)> &,std::integer_sequence<_Ty,0>)' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>,
1> _Ty=::size_t
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\thr\xthread(247): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Execute<0>(std::tuple<void (__cdecl World::* )(void)> &,std::integer_sequence<_Ty,0>)' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>,
1> _Ty=::size_t
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\thr\xthread(244): note: while compiling class template member function 'void std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *) noexcept'
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\thr\xthread(232): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *) noexcept' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\thr\xthread(259): note: see reference to class template instantiation 'std::_LaunchPad<_Target>' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\thread(49): note: see reference to function template instantiation 'void std::_Launch<std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<_Ty>>>(_Thrd_t *,_Target &&)' being compiled
1> with
1> [
1> _Ty=std::tuple<void (__cdecl World::* )(void)>,
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>d:\projects\blocky - opengl\src\chunk.cpp(339): note: see reference to function template instantiation 'std::thread::thread<void(__cdecl World::* )(void),,void>(_Fn &&)' being compiled
1> with
1> [
1> _Fn=void (__cdecl World::* )(void)
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\thr\xthread(240): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\thr\xthread(240): note: With the following template arguments:
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\thr\xthread(240): note: '_Callable=void (__cdecl World::* )(void)'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.10.25017\include\thr\xthread(240): note: '_Types={}'
**/
Also, I tried to put all members under public: scope. It does not help.

You have two problems:
The fist the compiler even tells you how to solve: You need to use the address-of operator & to get a pointer to a member function.
The second problem is that non-static member functions needs an object to be called on, which becomes the this pointer in the function. When creating threads this is passed as the first argument (it's not actually passed to the function though).
So to solve both your problems, your initializer need to look like
updateThread(&updateWorldLoop, this)

Related

Compilation issues in C++ while, trying to create a std:: thread by calling a member function in another object

WRT below code, I'm finding compilation issues while, trying to create a thread by calling a member function in another object.
th = std::thread(&AbcSFriend::S2F,this,friendObj);
is the culprit line causing below compilation error. If i remove this line iit compiles fine.
class AbcSFriend
{
public:
void S2F(Abc* ptr)
{}
};
class Abc
{
public:
std::thread th;
AbcSFriend frinedObj;
void FL()
{
th = std::thread(&AbcSFriend::S2F,this,friendObj);
}
};
Cannot generate copy-ctor or copy-assignment operator when UDT
contains a zero-sized array 1>C:\Program Files (x86)\Microsoft Visual
Studio 12.0\VC\include\functional(1149): error C2664: 'eUserErrorCode
std::_Pmf_wrap::operator ()(_Farg0 &,Abc *) const' : cannot convert argument 2 from 'AbcSFriend' to 'Abc *' 1>
with 1> [ 1> _Farg0=AbcSFriend 1> ] 1>
No user-defined-conversion operator available that can perform this
conversion, or the operator cannot be called 1> C:\Program
Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional(1137) :
see reference to function template instantiation '_UserErrorCode
std::_Bind,Abc
*,AbcSFriend>::_Do_call<,0x00,0x01>(std::tuple<>,std::_Arg_idx<0x00,0x01>)'
being compiled 1> C:\Program Files (x86)\Microsoft Visual
Studio 12.0\VC\include\functional(1137) : see reference to function
template instantiation '_UserErrorCode
std::_Bind,Abc
*,AbcSFriend>::_Do_call<,0x00,0x01>(std::tuple<>,std::_Arg_idx<0x00,0x01>)'
being compiled 1> C:\Program Files (x86)\Microsoft Visual
Studio 12.0\VC\include\thr/xthread(195) : see reference to function
template instantiation '_UserErrorCode
std::_Bind,Abc
*,AbcSFriend>::operator ()<>(void)' being compiled 1> C:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\thr/xthread(195) : see reference to function template instantiation '_UserErrorCode
std::_Bind,Abc
*,AbcSFriend>::operator ()<>(void)' being compiled 1> C:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\include\thr/xthread(192) : while compiling class template member function 'unsigned int
std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *)' 1>
with 1> [ 1>
_Target=std::_Bind,Abc
*,AbcSFriend> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\thr/xthread(187) : see
reference to function template instantiation 'unsigned int
std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *)' being
compiled 1> with 1> [ 1>
_Target=std::_Bind,Abc
*,AbcSFriend> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\thr/xthread(205) : see
reference to class template instantiation 'std::_LaunchPad<_Target>'
being compiled 1> with 1> [ 1>
_Target=std::_Bind,Abc
*,AbcSFriend> 1> ] 1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\thread(49) : see
reference to function template instantiation 'void
std::_Launch,Abc
*,AbcSFriend>>(_Thrd_t *,_Target &&)' being compiled 1> with 1> [ 1>
_Target=std::_Bind,Abc
*,AbcSFriend> 1> ] 1> ....\Sources\SOMEPLACESource.cpp(254) : see reference to function
template instantiation 'std::thread::thread(_Fn &&,Abc const
&&,AbcSFriend &)' being compiled 1> with 1> [ 1>
_Fn=eUserErrorCode (__cdecl AbcSFriend:: )(Abc *)
frinedObj (in AbcSFriend frinedObj;)
is not
friendObj (in th = std::thread(&AbcSFriend::S2F,this,friendObj);).
Fix the spelling.
As 'Maxim Egorushkin' says, try:
class AbcSFriend
{
public:
void S2F(class Abc* ptr);
};
class Abc
{
public:
std::thread th;
AbcSFriend friendObj;
void FL()
{
th = std::thread(&AbcSFriend::S2F, &friendObj, this);
}
};
I think the correct order of arguments is:
th = std::thread(&AbcSFriend::S2F, &friendObj, this);
It also makes sense to reverse the order of the declaration of members th and friendObj because currently friendObj destroys before th leaving open a possibility of th using friendObj after friendObj destroyed. Declare friendObj first and th last.

vector insert() warning message

I'm a c++ beginner. I get this warning message in my code:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(208): warning C4244: 'initializing' : conversion from 'double' to 'int', possible loss of data
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(280) : see reference to function template instantiation 'void std::allocator<_Ty>::construct<double&>(int *,_Other)' being compiled
1> with
1> [
1> _Ty=int,
1> _Other=double &
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector(668) : see reference to function template instantiation 'void std::_Cons_val<std::allocator<_Ty>,int,double&>(_Alloc &,_Ty1 *,_Ty2)' being compiled
1> with
1> [
1> _Ty=int,
1> _Alloc=std::allocator<int>,
1> _Ty1=int,
1> _Ty2=double &
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector(688) : see reference to function template instantiation 'void std::vector<_Ty>::emplace_back<double&>(_Valty)' being compiled
1> with
1> [
1> _Ty=int,
1> _Valty=double &
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\vector(675) : see reference to function template instantiation 'std::_Vector_iterator<_Myvec> std::vector<_Ty>::emplace<double&>(std::_Vector_const_iterator<_Myvec>,_Valty)' being compiled
1> with
1> [
1> _Myvec=std::_Vector_val<int,std::allocator<int>>,
1> _Ty=int,
1> _Valty=double &
1> ]
1> preprocessDoc.cpp(14054) : see reference to function template instantiation 'std::_Vector_iterator<_Myvec> std::vector<_Ty>::insert<double&>(std::_Vector_const_iterator<_Myvec>,_Valty)' being compiled
1> with
1> [
1> _Myvec=std::_Vector_val<int,std::allocator<int>>,
1> _Ty=int,
1> _Valty=double &
1> ]
The code compiles without any error however I want to get rid of this warning. The line where I am getting the warning is:
void PreprocessDoc::AddDisplay(double d_display, int pattern)
{
if(pattern==1)
{
d_displayYT.insert(d_displayYT.end(), d_display); //this line
YTtoYrn();
}
}
Any help would be good
_Myvec=std::_Vector_val<int,std::allocator<int>>,
The compiler is telling you that you're converting a double to int. If the double is say 42.666 what is stored is just 42. It's warning you in case this was not intended.
If that's really what you want then do as David suggests. If it's not then you need to change the type the vector holds.
Change:
d_displayYT.insert(d_displayYT.end(), d_display); //this line
to:
d_displayYT.insert(d_displayYT.end(), static_cast<int>(d_display));

sorting vector of structs by integer [duplicate]

This question already has answers here:
problem sorting using member function as comparator
(9 answers)
Closed 7 years ago.
Im trying to sort vector of structs. I saw this and this examples.
this is my code:
.h file:
// I didn't mention all the includes and namespace
class fileLoader
{
struct commands
{
int time;
string name;
};
commands resultStruct;
vector<commands> resultVector
private:
void sortFunction();
bool compareByTime(const commands &a, const commands &b);
}
.cpp file:
void fileLoader::sortResults()
{
sort(resultVector.begin(), resultVector.end(), compareByTime);
}
bool fileLoader::compareByTime(const commands &a, const commands &b)
{
return a.time < b.time;
}
this is the compilation error I get:
error C3867: 'fileLoader::compareByTime': function call missing argument list; use '&fileLoader::compareByTime' to create a pointer to member
error C2780: 'void std::sort(_RanIt,_RanIt)' : expects 2 arguments - 3 provided
c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(3639) : see declaration of 'std::sort'
when I tried to change compareByTime to &fileLoader::compareByTime, I got this compilation error:
error C2064: term does not evaluate to a function taking 2 arguments
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(3776) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> std::_Unguarded_partition<_RanIt,_Pr>(_RanIt,_RanIt,_Pr)' being compiled
1> with
1> [
1> _Ty1=fileLoader::commands *,
1> _Ty2=fileLoader::commands *,
1> _RanIt=fileLoader::commands *,
1> _Pr=bool (__thiscall fileLoader::* )(const fileLoader::commands &,const fileLoader::commands &)
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(3806) : see reference to function template instantiation 'void std::_Sort<fileLoader::commands*,__w64 int,_Pr>(_RanIt,_RanIt,_Diff,_Pr)' being compiled
1> with
1> [
1> _Pr=bool (__thiscall fileLoader::* )(const fileLoader::commands &,const fileLoader::commands &),
1> _RanIt=fileLoader::commands *,
1> _Diff=__w64 int
1> ]
std::sort<std::_Vector_iterator<_Myvec>,bool(__thiscall fileLoader::* )(const fileLoader::commands &,const fileLoader::commands &)>(_RanIt,_RanIt,_Pr)' being compiled
1> with
1> [
1> _Myvec=std::_Vector_val<fileLoader::commands,std::allocator<fileLoader::commands>>,
1> _RanIt=std::_Vector_iterator<std::_Vector_val<fileLoader::commands,std::allocator<fileLoader::commands>>>,
1> _Pr=bool (__thiscall fileLoader::* )(const fileLoader::commands &,const fileLoader::commands &)
1> ]
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(3720): fatal error C1903: unable to recover from previous error(s); stopping compilation
1>
1>Build FAILED.
I will be happy for some help.
thanks.
First fix all the typos (missing semicolons etc).
Then change your sorting function to static bool compareByTime(const commands &a, const commands &b);
Short answer
Make compareByTime static (or 'global' outside class)
Explanation
Member functions require this to be passed to them somehow, so two argument member function is probably 3 argument function. So compiler can't use it when it needs 2 arguments comparator.

Failure when casting NULL/nullptr to std::function<>&

This code fails to build in VC2013: (EDIT: I'm not asking why it fails to build)
#include <functional>
struct MyStruct
{
std::function<void()> m_Func;
MyStruct( const std::function<void()>& func) : m_Func(func) {}
};
int main()
{
MyStruct rc( NULL );
return 0;
}
With error:
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(283): error C2064: term does not evaluate to a function taking 0 arguments
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(228) : see reference to function template instantiation '_Ret std::_Callable_obj<int,false>::_ApplyX<_Rx,>(void)' being compiled
1> with
1> [
1> _Ret=void
1> , _Rx=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(228) : see reference to function template instantiation '_Ret std::_Callable_obj<int,false>::_ApplyX<_Rx,>(void)' being compiled
1> with
1> [
1> _Ret=void
1> , _Rx=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(226) : while compiling class template member function 'void std::_Func_impl<_MyWrapper,_Alloc,_Ret,>::_Do_call(void)'
1> with
1> [
1> _Alloc=std::allocator<std::_Func_class<void,>>
1> , _Ret=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(495) : see reference to class template instantiation 'std::_Func_impl<_MyWrapper,_Alloc,_Ret,>' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_Func_class<void,>>
1> , _Ret=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(396) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> , _Fty=int
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(396) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> , _Fty=int
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(385) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,>>>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Fty=int
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(385) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,>>>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Fty=int
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset<_Ty>(_Fty &&)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Fty=int
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset<_Ty>(_Fty &&)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=int
1> , _Fty=int
1> ]
1> f:\work\teststdfunction\teststdfunction.cpp(16) : see reference to function template instantiation 'std::function<void (void)>::function<int>(_Fx &&)' being compiled
1> with
1> [
1> _Fx=int
1> ]
1> f:\work\teststdfunction\teststdfunction.cpp(16) : see reference to function template instantiation 'std::function<void (void)>::function<int>(_Fx &&)' being compiled
1> with
1> [
1> _Fx=int
1> ]
(Note the '_Fx=int' at the last two reported errors).
I can live with that, as changing MyStruct rc(NULL) to MyStruct rc(nullptr) solves the error. Two things however remain a mystery:
1) Removing the const qualifier from MyStruct ctor (MyStruct( std::function<void()>& func) gives a very, very different error:
1>f:\work\main\dev\common\teststdfunction\teststdfunction\teststdfunction.cpp(16):
error C2664: 'MyStruct::MyStruct(const MyStruct &)' : cannot convert
argument 1 from 'int' to 'std::function &'
Which makes more sense than the original error, and now fixing NULL to nullptr doesn't solve it. Why does int (or nullptr) refuse to cast to std::function<>& but agree to cast to a const std::function<>& ?
2) The original code compiles and works as expected in VS2010. Is it an obscure VS2010 library bug?
EDIT:
As far as the const/non const question goes, I now think the casting involved and potential type mismatch are probably a red herring. The argument passed - either NULL or nullptr - is a literal and thus a const. It just cannot bind to a non const reference. For example:
const int& a = 8; // Ok
int& b = 9; // error C2440: 'initializing' : cannot convert from 'int' to 'int &'
Does that sound right? Am I still missing something?
The special here has to do with constructor template constraints and other implicit conversions.
The reason why nullptr works is because std::function has a particular constructor taking it. This constructor will always be the best match for that argument because function templates are ranked as lower preference, all else being equal.
Normally, 0 will implicitly convert to nullptr and that's fine. The problem is that it can also be passed to the unconstrained function template constructor which constructs from function objects. This does not require an implicit conversion, so all is not equal, so this constructor is preferred- which results in the error that you see that int is not a valid function object.
libstdc++ and libc++ don't not exhibit this behaviour because they have implemented the C++14 fix for this problem, which constrains the constructor. C++11 did not so this behaviour is quite conforming for a C++11 implementation.
This kind of issue is why NULL is a terrible thing that you shouldn't use. In fact, the VS2010 team had to rush nullptr out the door as an additional feature in the last minute because NULL interacts so badly with every other feature in C++, ever, and especially with C++11.
For const vs non-const references, other answers have explained that issue adequately.
There are other WTFs you can find when using std::function without the constrained constructor fix shipped in C++14- this isn't the only one. The long and short is that it's a defect in the C++11 Standard, and not in VS. VS2010 compiling it is probably a compiler overload resolution bug.
Casting a T to a U& never works, and that's intentionally. You can cast to a U const&. The reason is that changes to the temporary U object wouldn't propagate back to the T value.
VS2010 is slightly buggy in this respect, and did allow the cast (but with the proper settings, will warn about it)

std::make_shared gives error i dont understand

i have map that looks like this:
typedef std::map<PuzzlePartLocation, std::shared_ptr<PuzzleObj>> ComponentsMap;
now i try to set this map with elements via fucntion like this:
void ComponentMadiator::Register(const PuzzlePartLocation puzzlePartLocation,PuzzleObj* puzzleObj)
{
componentsMap[puzzlePartLocation] = std::make_shared<PuzzleObj>(puzzleObj);
}
i just call it like this :
PuzzleObj* pPuzzleObjStickLeft = new PuzzleObj()
pComponentMadiator->Register(1,pPuzzleObjStickLeft );
PuzzleObj contains memeber from type IImageComponent *
PuzzleObj inherits from base class
but it give me error like this :
1>c:\program files\microsoft visual studio 11.0\vc\include\memory(873): error C2664: 'PuzzleObj::PuzzleObj(IImageComponent *)' : cannot convert parameter 1 from 'PuzzleObj *' to 'IImageComponent *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1> c:\program files\microsoft visual studio 11.0\vc\include\memory(972) : see reference to function template instantiation 'std::_Ref_count_obj<_Ty>::_Ref_count_obj<PuzzleObj*&>(_V0_t)' being compiled
1> with
1> [
1> _Ty=PuzzleObj,
1> _V0_t=PuzzleObj *&
1> ]
1> c:\program files\microsoft visual studio 11.0\vc\include\memory(972) : see reference to function template instantiation 'std::_Ref_count_obj<_Ty>::_Ref_count_obj<PuzzleObj*&>(_V0_t)' being compiled
1> with
1> [
1> _Ty=PuzzleObj,
1> _V0_t=PuzzleObj *&
1> ]
1> d:\dev\cpp\cocos2d-x\cocos2d-x-3.0beta2\cocos2d-x-3.0beta2\projects\neonbreaker\classes\componentmadiator.cpp(23) : see reference to function template instantiation 'std::shared_ptr<_Ty> std::make_shared<PuzzleObj,PuzzleObj*&>(_V0_t)' being compiled
1> with
1> [
1> _Ty=PuzzleObj,
1> _V0_t=PuzzleObj *&
1> ]
std::make_shared<PuzzleObj> creates a new PuzzleObj for you. What you need is std::shared_ptr<PuzzleObj>(puzzleObj).
More importantly
void ComponentMadiator::Register(const PuzzlePartLocation puzzlePartLocation,PuzzleObj* puzzleObj);
should be declared as:
void ComponentMadiator::Register(const PuzzlePartLocation puzzlePartLocation, std::shared_ptr<PuzzleObj> const& puzzleObj);
because it shares ownership of puzzleObj by storing it in the container and that must be communicated in function's interface.
And call it like so:
std::shared_ptr<PuzzleObj> pPuzzleObjStickLeft(std::make_shared<PuzzleObj>());
pComponentMadiator->Register(1, pPuzzleObjStickLeft);