View more

View more

View more

Image of the Day Submit

IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

unique_ptr private member

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

14 replies to this topic

#1KingofNoobs  Members

Posted 28 November 2012 - 04:14 AM

Hello,

Can someone tell me why line (1) does not generate a compiler error while line (2) does?

(1)mAtlasList.begin()->operator*().GetName();
(2)auto IsLevel1Atlas = [](std::unique_ptr<Atlas> atlas) -> bool { return atlas->GetName() == L"Level1Atlas"; };
auto tempAtlasPtr = std::find_if(mAtlasList.begin(), mAtlasList.end(), IsLevel1Atlas);
const Sprite * tempSpritePtr = &(tempAtlasPtr->operator*().GetSpriteList().find(L"Background")->second);

The error generated is: error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'

Thanks.

I wonder as I wander...

http://www.davesgameoflife.com

#2wqking  Members

Posted 28 November 2012 - 04:21 AM

IsLevel1Atlas's parameter is a value of unique_ptr, you can't copy a unique_ptr.
Change IsLevel1Atlas to
auto IsLevel1Atlas = [](const std::unique_ptr<Atlas> & atlas) -> bool { return atlas->GetName() == L"Level1Atlas"; };

The first one works I guess your list::push_back must implement rvalue reference (&&) version?

Edited by wqking, 28 November 2012 - 04:24 AM.

http://www.cpgf.org/
cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.
v1.5.5 was released. Now supports tween and timeline for ease animation.

#3KingofNoobs  Members

Posted 28 November 2012 - 04:26 AM

wqking,

WOW! Thank you. You really solved my problem this time, and that makes sense.

Best,

-Dave ottley

I wonder as I wander...

http://www.davesgameoflife.com

#4KingofNoobs  Members

Posted 28 November 2012 - 05:22 AM

Hello again,

Is something like this possible? I am getting the same error here, which leads me to believe that a vector<unique_ptr<somethin> > is not possible:

const Rect GetSourceRect(const std::unique_ptr<Animation>& currentAnimation, uint32_t frameNumInAnimation) const
{
// Calculate position of current animation frame
auto i = std::find(mAnimations.begin(), mAnimations.end(), currentAnimation); // error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'

As you can see I passed the unique_ptr as a const &, but when I use algorithms, there appear to be copies being made here and there. Is there a solution to this?

Thanks,

-Dave Ottley

Edited by KingofNoobs, 28 November 2012 - 05:31 AM.

I wonder as I wander...

http://www.davesgameoflife.com

#5BitMaster  Members

Posted 28 November 2012 - 05:30 AM

When running into a problem it is important to post the exact error.

#6KingofNoobs  Members

Posted 28 November 2012 - 05:31 AM

BitMaster,

Sorry about that. I have edited the post above. Also, the error is:

error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'

I wonder as I wander...

http://www.davesgameoflife.com

#7BitMaster  Members

Posted 28 November 2012 - 05:39 AM

Without knowing the details it is not possible to be sure but does a comparison like
(instance of std::unique_ptr<somethin>) == (instance of std::unique_ptr<Animation>)
make sense at all? You might have to define a custom predicate for whatever it is you want and use std::find_if.

On a sidenote, the error is still not complete the output will contain a few more lines after the actual error codes to define exactly what kind of types T is in each case.

#8KingofNoobs  Members

Posted 28 November 2012 - 05:47 AM

The original problem was that I was having to default construct animations. For my game, animations come out of a file called an "atlas" file. There should be no way to default construct either an atlas or a sprite, or an animation (the ordering is atlas->sprite->animation, each one owning one or more of the item following it on the list). Thus, when I want to create a SpriteInstance, I have to pass a "starting animation" but rather than default construct one and fill in the fields by hand, I want to force myself to use the "unique" and only copy instantiated by the file. So I thought that changing the atlas and sprite classes to hold pointers to animations rather than animations themselves, that I could solve this problem. Wanting to avoid memory leaks, I thought I would go with the unique_ptr, however, I'm not sure if it is possible given the current errors. I think it should be but don't want to waste too much time on the issue, when I could just use raw pointers and delete.

The full error is below:

error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
1> with
1> [
1> _Ty=Animation
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
1> with
1> [
1> _Ty=Animation
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
1> with
1> [
1> _Ty=std::unique_ptr<Animation>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(751) : see reference to function template instantiation 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<Animation>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include ype_traits(743) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<Animation>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\vector(655) : see reference to class template instantiation 'std::is_empty<_Ty>' being compiled
1> with
1> [
1> _Ty=std::allocator<std::unique_ptr<Animation>>
1> ]
1> c:\users\mrmerchantman\dropbox\zzz_c++\projects\blockbuster\source\graphics\sprite.h(37) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<Animation>

I wonder as I wander...

http://www.davesgameoflife.com

#9KingofNoobs  Members

Posted 28 November 2012 - 05:51 AM

Hello,

I just realized that I am trying to share the pointers, so shared_ptr will be better. Thanks for your help.

-Dave Ottley

I wonder as I wander...

http://www.davesgameoflife.com

#10EddieV223  Members

Posted 01 December 2012 - 05:42 PM

I just want to point out that this

should be

mAtlasList.push_back( std::move( std::unique_ptr<Atlas>(new Atlas(MASTER_ATLAS_MAINMENU)) ) );

But if you really are trying to pass around multiple smart pointers to the same object you should use shared_ptr

If this post or signature was helpful and/or constructive please give rep.

// C++ Video tutorials

// Easy to learn 2D Game Library c++

SFML2.2 Tutorials http://www.sfml-dev.org/tutorials/2.2/

// Excellent 2d physics library Box2D

// SFML 2 book

#11SiCrane  Moderators

Posted 01 December 2012 - 05:50 PM

There's no point in adding the std::move() call. The unique_ptr is already an rvalue because it's a temporary.

#12BitMaster  Members

Posted 03 December 2012 - 04:38 AM

There's no point in adding the std::move() call. The unique_ptr is already an rvalue because it's a temporary.

I'm myself still a bit unsure about all the details of rvalues, but wouldn't it be more correct to say "unnamed temporary" because not every temporary automatically is an rvalue?

#13SiCrane  Moderators

Posted 03 December 2012 - 08:50 AM

No, every temporary is automatically an rvalue; it's part of the definition of rvalue. It's possible to bind a temporary to a named non-rvalue reference, but that named reference is itself not a temporary.

#14BitMaster  Members

Posted 03 December 2012 - 09:13 AM

For the record, I think I found where I got myself confused from back where I read this. An rvalue reference can (easily) become an unexpected lvalue (because it has a name). In the following scenario the std::move is needed to use the move assignment operator:
void doSomething(X&& x)
{
X anotherX = std::move(x);
// whatever...
}


#15SiCrane  Moderators

Posted 03 December 2012 - 04:22 PM

Of course in this case neither a temporary unique_ptr nor a rvalue reference to one needs to be used. std::vector::emplace_back() can be used to construct the object in place directly without bothering with a move.
mAtlasList.emplace_back(new Atlas(MASTER_ATLAS_MAINMENU));


Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.