std::unique_ptr<TJSONObject>

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

std::unique_ptr<TJSONObject>

Postby Lena » Wed Mar 11, 2015 9:38 am

How fix it?
Code: Select all
#include <System.JSON.hpp>
#include <memory>

 std::unique_ptr<TJSONObject> LJSONObject(new TJSONObject());
 String GJSONString = L"test";
 LJSONObject = dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(TEncoding::ASCII->GetBytes(GJSONString), 0));




[bcc32 Error] WebModuleUnit1.cpp(54): E2285 Could not find a match for 'operator std::unique_ptr<TJSONObject,std::default_delete<TJSONObject> >::= <_Ty2,_Dx2>(TJSONObject *)'
Full parser context
WebModuleUnit1.cpp(22): parsing: void _fastcall TWebModule1::WebModule1DefaultHandlerAction(TObject *,TWebRequest *,TWebResponse *,bool &)
Lena
BCBJ Master
BCBJ Master
 
Posts: 567
Joined: Sun Feb 06, 2011 1:28 pm

Re: std::unique_ptr<TJSONObject>

Postby rlebeau » Wed Mar 11, 2015 4:02 pm

Unlike std::auto_ptr, std::unique_ptr does not allow you to assign a raw object pointer to it using 'operator=()'. You can only assign another std::unique_ptr object (so it can transfer ownership of the owned pointer). That is what the compiler is telling you (when you strip off the overbearing template syntax):

Could not find a match for 'operator=(TJSONObject *)'


This is by design. std::unique_ptr is intentionally move-assignable but not copy-assignable. The operator=(T*) copy-assignment operator is explicitly disabled.

To do what you are attempting, you have to use the reset() method instead:

Code: Select all
std::unique_ptr<TJSONObject> LJSONObject(new TJSONObject());
String GJSONString = L"test";
LJSONObject.reset(dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(TEncoding::ASCII->GetBytes(GJSONString), 0)));


But there is no point in constructing and assigning the std::unique_ptr using separate operations since you are ignoring the initial TJSONObject you create:

Code: Select all
String GJSONString = L"test";
std::unique_ptr<TJSONObject> LJSONObject(dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(TEncoding::ASCII->GetBytes(GJSONString), 0)));


Which, of course, is a memory leak if ParseJSONValue() returns something other than a TJSONObject, so you need to fix your logic:

Code: Select all
String GJSONString = L"test";
std::unique_ptr<TJSONValue> LJSONValue(TJSONObject::ParseJSONValue(TEncoding::ASCII->GetBytes(GJSONString), 0));
TJSONObject *LJSONObject = dynamic_cast<TJSONObject*>(LJSONValue.get());


Lastly, using TEncoding is overkill as ParseJSONValue() has an overload that accepts a System::String as input:

Code: Select all
std::unique_ptr<TJSONValue> LJSONValue(TJSONObject::ParseJSONValue(GJSONString));
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1528
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: std::unique_ptr<TJSONObject>

Postby Lena » Thu Mar 12, 2015 1:24 am

Thank you very much for the detailed explanation!
Lena
BCBJ Master
BCBJ Master
 
Posts: 567
Joined: Sun Feb 06, 2011 1:28 pm


Return to Technical

Who is online

Users browsing this forum: No registered users and 13 guests