Calling std::move() on derefrence value of smart pointer - c++

class A{
public:
void AddObject(MsgType msg){
msg_queue.push_back(msg);
}
private:
std::queue<MsgType> msg_queue;
}
I have this class A and its method AddObject(). There are 2 types of clients for this class. First type is where they get only boost::sharedPtr<MsgType> and other client has std::shared_ptr<MsgType> or const MsgType&.
What should be signature of AddObject() so that I can avoid conversion or making copy here. If I use AddObject(MsgType msg) then I will have to call from client side:
boost::shared_ptr<MsgType> msg;
AddObject(std::move(*msg));
or
std::shared_ptr<MsgType> msg;
AddObject(std::move(*msg));
and I can use std::move() in AddObject() to store it in queue.
Considering performance, what should be my API here?
Size of MsgType is around 1.4 MB which is protobuf message. For protobuf move costructors are very costly. So looks like I cannot use std::move here.

The way you have originally written AddObject(), it makes no assumptions about the ownership of the input MsgType. It doesn't know, or care, how the MsgType is allocated, or who should own it. In that scenario, the only valid thing you can do is make a copy for yourself, which is what you currently do.
If you want AddObject() to take ownership without making a copy, then AddObject() needs to be explicit about how it expects ownership to be managed. You express ownership semantics in one of two ways:
require exclusive ownership by using std::unique_ptr (or boost::unique_ptr):
class A{
public:
void AddObject(std::unique_ptr<MsgType> msg){
msg_queue.push(std::move(*msg));
}
private:
std::queue<MsgType> msg_queue;
};
Or better:
class A{
public:
void AddObject(std::unique_ptr<MsgType> msg){
msg_queue.push(std::move(msg));
}
private:
std::queue<std::unique_ptr<MsgType>> msg_queue;
};
share ownership by using std::shared_ptr (or boost::shared_ptr):
class A{
public:
void AddObject(std::shared_ptr<MsgType> &msg){
msg_queue.push(msg);
}
private:
std::queue<std::shared_ptr<MsgType>> msg_queue;
};
Otherwise, all you can really do is std::move() the contents of the input MsgType, and then let the caller worry about deallocating the MsgType later on:
class A{
public:
void AddObject(MsgType &msg){
msg_queue.push(std::move(msg));
}
private:
std::queue<MsgType> msg_queue;
};
However, in your situation, this last option is probably not very viable since you claim that moving a protobuf object is costly. In that case, you should move around just a pointer to a protobuf object rather than moving around the object itself. That is where (std|boost)::unique_ptr and (std|boost)::shared_ptr come into play.
If you want to code your class to support both std and boost smart pointers, then you will have to either overload AddObject() for each type, or give it a template parameter that you can specialize on as needed.

Related

Why does enable_shared_from_this lack direct access to the embedded weak_ptr?

I want to use boost signals2 with automatic connection management in a multithreaded application. My class inherits from enable_shared_from_this<> and i want to connect a member method from within another member method. The connection might be rebuilt frequently so my code should be as fast as possible (despite from the boost signals2 performance itself):
typedef boost::signals2::signal<void ()> signal_type;
struct Cat : public enable_shared_from_this<Cat>
{
void meow ();
void connect (signal_type& s)
{
// can't write this
s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (weak_from_this ()));
// ok, but slow?! two temporary smart pointers
weak_ptr<Cat> const myself (shared_from_this ());
s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (myself));
}
// i am missing something like this in the base class
// protected:
// weak_ptr<Cat> const& weak_from_this ();
};
I know that my design goals might be conflicting (automatic connection management and thread safety but also fast code) but anyway:
Why does enable_shared_from_this<> lack direct access to the embedded weak_ptr<>? I can't see an opposing reason. Is there no use case similar to mine?
Is there a faster workaround than the one above?
Edit:
I know i can do somethink like this, but i want to avoid the additional storage/init-check penalty:
template <typename T>
struct enable_weak_from_this : public enable_shared_from_this<T>
{
protected:
weak_ptr<T> /* const& */ weak_from_this ()
{
if (mWeakFromThis.expired ())
{
mWeakFromThis = this->shared_from_this ();
}
return mWeakFromThis;
}
private:
weak_ptr<T> mWeakFromThis;
};
The reason you don't have access to the weak_ptr is that enable_shared_from_this doesn't have to use one. Having a weak_ptr is simply one possible implementation of enable_shared_from_this. It is not the only one.
Since enable_shared_from_this is part of the same standard library as shared_ptr, a more efficient implementation could be used than directly storing a weak_ptr. And the committee doesn't want to prevent that optimization.
// ok, but slow?! two temporary smart pointers
That's only one temporary smart pointer. Copy elision/movement should take care of anything but the first object.
It might be because there are no shared_ptr referencing the Cat instance. weak_ptr requires there to be at least one active shared_ptr.
Try placing a shared_ptr as member variable and assign to it first in the connect method:
typedef boost::signals2::signal<void ()> signal_type;
struct Cat : public enable_shared_from_this<Cat>
{
void meow ();
boost::shared_ptr<Cat> test;
void connect (signal_type& s)
{
test = shared_from_this();
s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (weak_from_this ()));
}
};
But basically, there can be no weak_ptr if there are no shared_ptr.
And if all shared_ptr disapear while the weak_ptr is still in use, then the weak_ptr could point to an non-existant object.
Note: My test should not be used in production code as it will cause the object to never be deallocated.

Learning c++11 smart pointer, it won't let me use implicit conversion like a pointer can?

I have a ISceneNode interface and from that a SceneNode base class.
From the SceneNode class derive MeshNode, AnimNode, LightNode, CameraNode, ect...
Now I have an actor class that through a method takes in a shared_ptr
and stores it in a field.
What I'd like to be able to do is send in any std::shared_ptr or other derived classes into the function that takes in a shared_ptr .
With bare pointers this would be an implicit conversion.
The solution that I came up with was to write a overload for each of the derives and then cast it within the method using dynamic_pointer_cast . That's just nasty there should be a better way.
Is there a way to get implicit casting, or a better way I don't know of to handle this?
What's the proper way to handle this?
void SomeFunc()
{
std::shared_ptr<MeshNode> pMeshNode( new MeshNode() );
gActor.SetNode( pMeshNode ); // won't compile.
// or do i have to do it like this
gActor.SetNode( std::dynamic_pointer_cast<ISceneNode> (pMeshNode) );
}
void Actor::SetNode( std::shared_ptr<ISceneNode> pNode )
{
mpNode = pNode;
}
// or do I have to do it like this? Making an over load for each derived.
void Actor::SetNode( std::shared_ptr<MeshNode> pMeshNode )
{
mpNode = std::dynamic_pointer_cast<ISceneNode> (pMeshNode);
}
You claim it won't compile, but the following test compiles and runs for me (VS2012, Clang, G++). You should post the error you're getting, as it's most likely something else.
#include <memory>
struct IBase {};
struct Derived : IBase {};
void Foo(std::shared_ptr<IBase> p) {}
int main()
{
std::shared_ptr<Derived> d;
Foo(d);
}
I bet you are using VS2010? I found some problems with smart pointers support there? On a compiler with better C++11 support (eg. VS2012, gcc, clang) it should compile fine. However I would suggest you some extensions:
class Actor {
std::shared_ptr<ISceneNode> mpNode;
public:
void SetNode(std::shared_ptr<ISceneNode> pNode)
{ mpNode = std::move(pNode); }
};
void SomeFunc()
{
gActor.SetNode(std::make_shared<MeshNode>());
}
It is always better to allocate std::shared_ptr with std::make_shared<T>() which saves you one dynamic allocation and even up to the half of shared state memory overhead. You should also either pass std::shared_ptr as a reference to a function or at least move it to a new value like I did. You could also consider using std::unique_ptr which makes it even more effective (no shared state memory overhead and thread safe reference counting) and makes the design better (clear ownership). You can use in a very similar way:
class Actor {
std::unique_ptr<ISceneNode> mpNode;
public:
void SetNode(std::unique_ptr<ISceneNode> pNode)
{ mpNode = std::move(pNode); }
};
void SomeFunc()
{
gActor.SetNode(std::unique_ptr<MeshNode>(new MeshNode));
}

pass lambda expression as member function pointer in c++

I have a framework function which expects an object and a member function pointer (callback), like this:
do_some_work(Object* optr, void (Object::*fptr)()); // will call (optr->*fptr)()
How can I pass a lambda expression to it? Want to do somethink like this:
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, [](){ /* this lambda I want to pass */ });
}
};
The meaning of it all is to not clutter the interface of MyObject class with callbacks.
UPD
I can improve do_some_work in no way because I don't control framework and because actually it isn't one function, there're hundreds of them. Whole framework is based on callbacks of that type. Common usage example without lambdas:
typedef void (Object::*Callback)();
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, (Callback)(MyClass::do_work));
}
void do_work()
{
// here the work is done
}
};
SOLUTION Here's my solution based on Marcelo's answer:
class CallbackWrapper : public Object
{
fptr fptr_;
public:
CallbackWrapper(void (*fptr)()) : fptr_(fptr) { }
void execute()
{
*fptr_();
}
};
class MyObject : public Object
{
void mystuff()
{
CallbackWrapper* do_work = new CallbackWrapper([]()
{
/* this lambda is passed */
});
do_some_work(do_work, (Callback)(CallbackWrapper::execute));
}
};
Since we create the CallbackWrapper we can control it's lifetime for the cases where the callback is used asynchonously. Thanks to all.
This is impossible. The construct (optr->*fptr)() requires that fptr be a pointer-to-member. If do_some_work is under your control, change it to take something that's compatible with a lambda function, such as std::function<void()> or a parameterised type. If it's a legacy framework that isn't under your control, you may be able to wrap it, if it's a function template, e.g.:
template <typename Object>
do_some_work(Object* optr, void (Object::*fptr)());
Then, you can implement a wrapper template:
template <typename F>
void do_some_work(F f) {
struct S {
F f;
S(F f) : f(f) { }
void call() { f(); delete this; }
};
S* lamf = new S(f);
do_some_work(lamf, &S::call);
}
class MyObject // You probably don't need this class anymore.
{
void mystuff()
{
do_some_work([](){ /* Do your thing... */ });
}
};
Edit: If do_some_work completes asynchronously, you must allocate lamf on the heap. I've amended the above code accordingly, just to be on the safe side. Thanks to #David Rodriguez for pointing this out.
There are deeper problems with the approach that you are trying to take than the syntactical mismatch. As DeadMG suggests, the best solution is to improve the interface of do_some_work to take a functor of some sort (std::function<void()> in C++11 or with boost, or even a generic F on which operator() is called.
The solution provided by Marcelo solves the syntactical mismatch, but because the library takes the first element by pointer, it is the responsibility of the caller to ensure that the object will be alive when the callback is executed. Assuming that the callback is asynchronous, the problem with his solution (and other similar alternatives) is that the object can potentially be destroyed before the callback is executed, causing undefined behavior.
I would suggest that you use some form of plimp idiom, where the goal in this case would be to hide the need for callbacks (because the rest of the implementation might not need to be hidden you could use just another class to handle the callbacks but store it by value, if you don't want do have to dynamically allocate more memory):
class MyClass;
class MyClassCallbacks {
MyClass* ptr;
public:
MyClassCallbacks( MyClass* ptr ) : ptr(ptr) {}
// callbacks that execute code on `ptr`
void callback1() {
// do some operations
// update *ptr
}
};
class MyClass {
MyClassCallbacks callbackHandler;
public:
void mystuff() {
do_some_work( &callbackHandler, &MyClassHandler::callback1 );
}
};
In this design, the two classes are separated but represent a unique single entity, so it is fine to add a friend declaration and let MyClassCallbacks access the internal data in MyClass (both of them are one single entity, divided only to provide a cleaner interface, but coupling is already high, so adding the extra coupling requiered by friend is no problem).
Because there is a 1-1 relationship between MyClass and MyClassCallbacks instances, their lifetimes are bound and there would be no lifetime issues, except during destruction. During destruction you must ensure that there is no callback registered that can kick in while the MyClass object is being destroyed.
Since you are at it, you might want to walk the extra mile and do a proper pimpl: move all of the data and implementation into a different type that is held by pointer, and offer a MyClass that stores a pointer and offers just the public functions, implemented as forwarders to the pimpl object. This could be somehow tricky as you are using inheritance, and the pimpl idiom is a bit cumbersome to implement on type hierarchies (if you need to extend MyClass, deriving from Object could be done in the pimpl object, rather than the interface type).
I don't think you can do that. Your do_some_work() is declared to accept pointer to methods of class Object, so such should be provided. Otherwise optr->*fptr is invalid since the lambda is not member of Object. Probably you should try using std::function and adding the needed members of Object in its closure.
You must use std::function<void()>. Both function and member function pointers are highly unsuited to being callbacks.

Vector of pointers to instances of a templated class

I am implementing a task runtime system that maintains buffers for user-provided objects of various types. In addition, all objects are wrapped before they are stored into the buffers. Since the runtime doesn't know the types of objects that the user will provide, the Wrapper and the Buffer classes are templated:
template <typename T>
class Wrapper {
private:
T mdata;
public:
Wrapper() = default;
Wrapper(T& user_data) : mdata(user_data) {}
T& GetData() { return mdata; }
...
};
template <typename T>
class Buffer {
private:
std::deque<Wrapper<T>> items;
public:
void Write(Wrapper<T> wd) {
items.push_back(wd);
}
Wrapper<T> Read() {
Wrapper<T> tmp = items.front();
items.pop_front();
return tmp;
}
...
};
Now, the runtime system handles the tasks, each of which operates on a subset of aforementioned buffers. Thus, each buffer is operated by one or more tasks. This means that a task must keep references to the buffers since the tasks may share buffers.
This is where my problem is:
1) each task needs to keep references to a number of buffers (this number is unknown in compile time)
2) the buffers are of different types (based on the templeted Buffer class).
3) the task needs to use these references to access buffers.
There is no point to have a base class to the Buffer class and then use base class pointers since the methods Write and Read from the Buffer class are templeted and thus cannot be virtual.
So I was thinking to keep references as void pointers, where the Task class would look something like:
class Task {
private:
vector<void *> buffers;
public:
template<typename T>
void AddBuffer(Buffet<T>* bptr) {
buffers.push_back((void *) bptr);
}
template<typename T>
Buffer<T>* GetBufferPtr(int index) {
return some_way_of_cast(buffers[index]);
}
...
};
The problem with this is that I don't know how to get the valid pointer from the void pointer in order to access the Buffer. Namely, I don't know how to retain the type of the object pointed by buffers[index].
Can you help me with this, or suggest some other solution?
EDIT: The buffers are only the implementation detail of the runtime system and the user is not aware of their existence.
In my experience, when the user types are kept in user code, run-time systems handling buffers do not need to worry about the actual type of these buffer. Users can invoke operations on typed buffers.
class Task {
private:
vector<void *> buffers;
public:
void AddBuffer(char* bptr) {
buffers.push_back((void *) bptr);
}
char *GetBufferPtr(int index) {
return some_way_of_cast(buffers[index]);
}
...
};
class RTTask: public Task {
/* ... */
void do_stuff() {
Buffer<UserType1> b1; b1Id = b1.id();
Buffer<UserType2> b2; b2Id = b2.id();
AddBuffer(cast(&b1));
AddBuffer(cast(&b2));
}
void do_stuff2() {
Buffer<UserType1> *b1 = cast(GetBufferPtr(b1Id));
b1->push(new UserType1());
}
};
In these cases casts are in the user code. But perhaps you have a different problem. Also the Wrapper class may not be necessary if you can switch to pointers.
What you need is something called type erasure. It's way to hide the type(s) in a template.
The basic technique is the following:
- Have an abstract class with the behavior you want in declared in a type independent maner.
- Derive your template class from that class, implement its virtual methods.
Good news, you probably don't need to write your own, there boost::any already. Since all you need is get a pointer and get the object back, that should be enough.
Now, working with void* is a bad idea. As perreal mentioned, the code dealing with the buffers should not care about the type though. The good thing to do is to work with char*. That is the type that is commonly used for buffers (e.g. socket apis). It is safer than too: there is a special rule in the standard that allows safer conversion to char* (see aliasing rules).
This isn't exactly an answer to your question, but I just wanted to point out that the way you wrote
Wrapper<T> Read() {
makes it a mutator member function which returns by value, and as such, is not good practice as it forces the user write exception unsafe code.
For the same reason the STL stack::pop() member function returns void, not the object that was popped off the stack.

Polymorphic class member variable

I have a class messenger which relies on a printer instance. printer is a polymorphic base class and the actual object is passed to the messenger in the constructor.
For a non-polymorphic object, I would just do the following:
class messenger {
public:
messenger(printer const& pp) : pp(pp) { }
void signal(std::string const& msg) {
pp.write(msg);
}
private:
printer pp;
};
But when printer is a polymorphic base class, this no longer works (slicing).
What is the best way to make this work, considering that
I don’t want to pass a pointer to the constructor, and
The printer class shouldn’t need a virtual clone method (= needs to rely on copy construction).
I don’t want to pass a pointer to the constructor because the rest of the API is working with real objects, not pointers and it would be confusing / inconsistent to have a pointer as an argument here.
Under C++0x, I could perhaps use a unique_ptr, together with a template constructor:
struct printer {
virtual void write(std::string const&) const = 0;
virtual ~printer() { } // Not actually necessary …
};
struct console_printer : public printer {
void write(std::string const& msg) const {
std::cout << msg << std::endl;
}
};
class messenger {
public:
template <typename TPrinter>
messenger(TPrinter const& pp) : pp(new TPrinter(pp)) { }
void signal(std::string const& msg) {
pp->write(msg);
}
private:
std::unique_ptr<printer> pp;
};
int main() {
messenger m((console_printer())); // Extra parens to prevent MVP.
m.signal("Hello");
}
Is this the best alternative? If so, what would be the best way in pre-0x? And is there any way to get rid of the completely unnecessary copy in the constructor? Unfortunately, moving the temporary doesn’t work here (right?).
There is no way to clone polymorphic object without a virtual clone method. So you can either:
pass and hold a reference and ensure the printer is not destroyed before the messenger in the code constructing messenger,
pass and hold a smart pointer and create the printer instance with new,
pass a reference and create printer instance on the heap using clone method or
pass a reference to actual type to a template and create instance with new while you still know the type.
The last is what you suggest with C++0x std::unique_ptr, but in this case C++03 std::auto_ptr would do you exactly the same service (i.e. you don't need to move it and they are otherwise the same).
Edit: Ok, um, one more way:
Make the printer itself a smart pointer to the actual implementation. Than it's copyable and polymorphic at the same time at the cost of some complexity.
Expanding the comment into a proper answer...
The primary concern here is ownership. From you code, it is appears that each instance of messenger owns its own instance of printer - but infact you are passing in a pre-constructed printer (presumably with some additional state), which you need to then copy into your own instance of printer. Given the implied nature of the object printer (i.e. to print something), I would argue that the thing to which is it is printing is a shared resource - in that light, it makes no sense for each messenger instance to have it's own copy of printer (for example, what if you need to lock to access to std::cout)?
From a design point of view, what messenger needs on construction is actually really a pointer to some shared resource - in that light, a shared_ptr (better yet, a weak_ptr) is a better option.
Now if you don't want to use a weak_ptr, and you would rather store a reference, think about whether you can couple messenger to the type of printer, the coupling is left to the user, you don't care - of course the major drawback of this is that messenger will not be containable. NOTE: you can specify a traits (or policy) class which the messenger can be typed on and this provides the type information for printer (and can be controlled by the user).
A third alternative is if you have complete control over the set of printers, in which case hold a variant type - it's much cleaner IMHO and avoids polymorphism.
Finally, if you cannot couple, you cannot control the printers, and you want your own instance of printer (of the same type), the conversion constructor template is the way forward, however add a disable_if to prevent it being called incorrectly (i.e. as normal copy ctor).
All-in-all, I would treat the printer as a shared resource and hold a weak_ptr as frankly it allows better control of that shared resource.
Unfortunately, moving the temporary doesn’t work here (right?).
Wrong. To be, uh, blunt. This is what rvalue references are made for. A simple overload would quickly solve the problem at hand.
class messenger {
public:
template <typename TPrinter>
messenger(TPrinter const& pp) : pp(new TPrinter(pp)) { }
template <typename TPrinter>
messenger(TPrinter&& pp) : pp(new TPrinter(std::move(pp))) { }
void signal(std::string const& msg) {
pp->write(msg);
}
private:
std::unique_ptr<printer> pp;
};
The same concept will apply in C++03, but swap unique_ptr for auto_ptr and ditch the rvalue reference overload.
In addition, you could consider some sort of "dummy" constructor for C++03 if you're OK with a little dodgy interface.
class messenger {
public:
template <typename TPrinter>
messenger(TPrinter const& pp) : pp(new TPrinter(pp)) { }
template<typename TPrinter> messenger(const TPrinter& ref, int dummy)
: pp(new TPrinter())
{
}
void signal(std::string const& msg) {
pp->write(msg);
}
private:
std::unique_ptr<printer> pp;
};
Or you could consider the same strategy that auto_ptr uses for "moving" in C++03. To be used with caution, for sure, but perfectly legal and doable. The trouble with that is that you're influencing all printer subclasses.
Why don't you want to pass a pointer or a smart pointer?
Anyway, if you're always initializing the printer member in the constructor you can just use a reference member.
private:
printer& pp;
};
And initialize in the constructor initialization list.
When you have a golden hammer everything looks like nails
Well, my latest golden hammer is type erasure. Seriously I would not use it, but then again, I would pass a pointer and have the caller create and inject the dependency.
struct printer_iface {
virtual void print( text const & ) = 0;
};
class printer_erasure {
std::shared_ptr<printer_iface> printer;
public:
template <typename PrinterT>
printer_erasure( PrinterT p ) : printer( new PrinterT(p) ) {}
void print( text const & t ) {
printer->print( t );
}
};
class messenger {
printer_erasure printer;
public:
messenger( printer_erasure p ) : printer(p) {}
...
};
Ok, arguably this and the solutions provided with a template are the exact same thing, with the only slight difference that the complexity of type erasure is moved outside of the class. The messenger class has its own responsibilities, and the type erasure is not one of them, it can be delegated.
How about templatizing the class messanger ?
template <typename TPrinter>
class messenger {
public:
messenger(TPrinter const& obj) : pp(obj) { }
static void signal(printer &pp, std::string const& msg) //<-- static
{
pp->write(msg);
}
private:
TPrinter pp; // data type should be template
};
Note that, signal() is made static. This is to leverage the virtual ability of class printer and to avoid generating a new copy of signal(). The only effort you have to make is, call the function like,
signal(this->pp, "abc");
Suppose you have other datatypes then pp which are not related to template type, then those can be moved to a non template base class and that base can be inherited by messenger. I am not describing in much details but, I wish the point should be clearer.