how to pass a Unique Pointer - c++

I have a class Container, having a data member.
std::vector< std::unique_ptr<Sum_Function> > Functions;
This is how i add value to the vector.
MaxSize is the child of Sum_Function.
void WavefrontRenderer::AddMaxSize()
{
Container cont;
std::unique_ptr<Sum_Function> ptrMaxSize = std::make_unique<SumMaxSize>();
cont.AddFunction(ptrMaxSize);
}
this is the defination for Function in the Container class.
void Container::AddFunction(std::unique_ptr<Sum_Function> &func)
{
std::unique_ptr< Sum_Function > function(std::move(func));
this->Functions.push_back(function);
}
Is this the correct way to add Unique pointer to a vector.

To move an existing Sum_Function subclass object pointer into Functions you can do like this:
void AddFunction(std::unique_ptr<Sum_Function>& func) {
Functions.emplace_back(std::move(func));
}
...
Container c;
auto f = std::make_unique<SumMaxSize>();
c.AddFunction(f);
... or like this, which requires the argument to be an rvalue reference, which in turn makes the pointer-stealing more obvious:
void AddFunction(std::unique_ptr<Sum_Function>&& func) {
Functions.emplace_back(std::move(func));
}
...
Container c;
auto f = std::make_unique<SumMaxSize>();
// c.AddFunction(f); // Error, f is an lvalue
c.AddFunction(std::move(f)); // OK, xvalue
c.AddFunction(std::make_unique<SumMaxSize>()); // OK, prvalue
You could also provide a convenience member function in Container for creating it directly in the vector without the middle step:
template<typename T, class... Args>
void emplace_back(Args&&... args) {
Functions.emplace_back(std::make_unique<T>(std::forward<Args>(args)...));
}
And instead of doing make_unique first and calling AddFunction, just:
Container c;
c.emplace_back<SumMaxSize>();
The perfect forwarding in the emplace_back function template above will also make the in-place construction to work for subclasses with constructors that takes arguments:
struct BiasedSumFunc : Sum_Function {
BiasedSumFunc(int bias) : bias_(bias) {}
private:
int bias_;
};
...
Container c;
c.emplace_back<BiasedSumFunc>( -5 );

A unique_ptr can't be copied, only moved. So when calling push_back(), you need to use the overload that moves from an rvalue, not the one that copies from an lvalue:
void Container::AddFunction(std::unique_ptr<Sum_Function> &func)
{
std::unique_ptr< Sum_Function > function(std::move(func));
this->Functions.push_back(std::move(function));
}
Which makes the local function variable redundant, so you can remove it:
void Container::AddFunction(std::unique_ptr<Sum_Function> &func)
{
this->Functions.push_back(std::move(func));
}

Related

Unbinding std::bind in c++

I have a number of function pointers bound with their respective class objects:
ExampleClass EO;
std::function<void()> Example=std::bind(&ExampleClass::ExampleFunction, &EO);
However, I'd like to 'unbind' these at a later point, specifically to identify the specific class which each of the 'std::function's relate to.
auto Unbind(std::function<void()> &Example)->void
{
//Find which object &Example is bound with (in this case EO/ExampleClass)
}
What's the best way of doing this?
std::function performs type erasure. As per the name, it erases the real underlying types from the interface.
There is no way back from there.
If you want to preserve the type of the target object, then std::mem_fn might be what you want:
http://en.cppreference.com/w/cpp/utility/functional/mem_fn
You cannot do it with a function object.
A possibility is to construct a wrapper in which to store the reference to the method and the object.
Something like this:
template<typename T, typename Fn>
struct MemberFunctionPointer {
MemberFunctionPointer(T* ref, Fn fn) : m_ref(ref),
m_method(fn) { }
template<typename... Args>
auto operator()(Args&&... args) {
return (m_ref->*m_method)(std::forward<Args...>(args)...);
}
T* m_ref = nullptr; // a reference (pointer) to the object instance
Fn m_method = nullptr; // a reference to the function method
};
Note: this is just a scratch. You should add a more sophisticated interface. Moreover a helper function in order to create a MemberFunctionPointer object could be useful as well.
You can pass that kind of object instead of a simply function.
struct Foo {
void bar() {
// something
}
};
int main(int argc, char *argv[]) {
Foo f;
MemberFunctionPointer<Foo, decltype(&Foo::bar)> method(&f, &Foo::bar);
method(); // call the method on the object f.
assert(&f == method.get_obj_reference());
return 0;
}

factory, unique_ptr and static_cast

Consider polymorphic classes with a base object, a derived interface, and a final object:
// base object
struct object
{
virtual ~object() = default;
};
// interfaces derived from base object
struct interface1 : object
{
virtual void print_hello() const = 0;
template<typename T>
static void on_destruction(object* /*ptr*/)
{
std::cout << "interface1::on_destruction" << std::endl;
}
};
// final object
struct derived1 : interface1
{
virtual void print_hello() const override
{
std::cout << "hello" << std::endl;
}
static std::string get_type_name()
{
return "derived1";
}
};
In the real use case, final objects are defined through a plugin system, but that is not the point. Note that I want to be able to call on_destruction when an object is destroyed (see register_object below). I want to use these classes as follows:
int main()
{
// register derived1 as an instantiable object,
// may be called in a plugin
register_object<derived1>();
// create an instance using the factory system
auto instance = create_unique<interface1>("derived1");
instance->print_hello();
return 0;
}
Using std::unique_ptr to manage the objects, I ended up with the following code for register_object:
template<typename T>
using unique = std::unique_ptr<
T,
std::function<void(object*)> // object deleter
>;
namespace
{
std::map< std::string, std::function<unique<object>(void)> > factory_map;
}
template<typename T>
void register_object()
{
factory_map.emplace(
T::get_type_name(),
[]()
{
unique<T> instance{
new T,
[](object* ptr)
{
T::on_destruction<T>(ptr);
delete ptr;
}
};
return static_move_cast<object>(
std::move(instance)
);
}
);
}
And the create* functions:
unique<object> create_unique_object(const std::string& type_name)
{
auto f = factory_map.at(type_name);
return f();
}
template<typename T>
unique<T> create_unique(const std::string& type_name)
{
return static_move_cast<T>(
create_unique_object(type_name)
);
}
You noticed in register_object and create_unique the call to static_move_cast, which is declared as:
template<typename U, typename T, typename D>
std::unique_ptr<U, D>
static_move_cast
(
std::unique_ptr<T, D>&& to_move_cast
)
{
auto deleter = to_move_cast.get_deleter();
return std::unique_ptr<U, D>{
static_cast<U*>(
to_move_cast.release()
),
deleter
};
}
The goal behind static_move_cast is to allow static_cast on std::unique_ptr while moving the deleter during the cast. The code is working, but I feel like hacking std::unique_ptr. Is there a way to refactor the code to avoid my static_move_cast?
static_move_cast is unnecessary within register_object, since you can just use the converting constructor of unique_ptr template< class U, class E > unique_ptr( unique_ptr<U, E>&& u ):
unique<T> instance{
new T,
// ...
};
return instance;
Or, even simpler, construct and return a unique<object> directly, since T* is convertible to object*:
return unique<object>{
new T,
// ...
};
However for create_unique the use of static_move_cast is unavoidable, since the converting constructor of unique_ptr won't work for downcasts.
Note that shared_ptr has static_pointer_cast, which performs downcasts, but there is no corresponding facility for unique_ptr, presumably because it it is considered straightforward and correct to perform the cast yourself.
I would say it is good solution given the requirements. You transfer the responsibility to the caller of create_unique. He must give correct combination of type and string and string that is in the registry.
auto instance = create_unique<interface1>("derived1");
// ^^^^^^^^^^ ^^^^^^^^
// what if those two don't match?
You could improve it a bit by changing the static_cast to dynamic_cast. And the caller of create_unique should always check that he got non-null pointer before calling anything on it.
Or at least use dynamic_cast with assert in debug mode, so you catch mismatches while developing.
Alternative refactoring: Have separate factory for every existing interface.

auto x = make_x(...) and this

I have a class template S<T> and because the template parameter is sometimes hard write explicitly I also have a little helper function makeS(...) to deduce the template parameter.
Now the problem is that the constructor of S has a "side effect": it adds itself to a map which then will later be used to iterate over all instances of S. But this effectively makes S<T> s{...}; very different from auto s = makeS(...); (if RVO is not used).
Here is some code which hopefully shows what I'm trying to do. (Note: in the actual program, S has more than a single template parameter and all will be deduced in makeS)
#include <cassert>
#include <iostream>
#include <map>
#include <string>
#include <utility>
using namespace std;
struct Base
{
virtual ~Base() {}
virtual void f() const = 0;
};
static map<string, Base*> Map;
template <typename T>
struct S : Base
{
T Func;
Base* This;
S(string const& name, T func) : Func(std::move(func)), This(this)
{
//
// Automatically add this struct to Map...
//
Map.insert({name, this});
}
virtual void f() const override { Func(); }
};
template <typename T>
S<T> makeS(std::string const& name, T func)
{
return S<T>(name, std::move(func));
}
void func1()
{
std::cout << "func1\n";
}
int main()
{
struct Func2
{
void operator ()() const {
std::cout << "func2\n";
}
};
//
// This is not possible:
//
// S< ??? > s("s", [](){});
//
// This would be ok:
//
// auto F = [](){};
// S<decltype(F)> s("s", F);
//
auto s1 = makeS("s1", func1);
auto s2 = makeS("s2", Func2());
auto s3 = makeS("s3", [](){ std::cout << "func3\n"; });
//
// Manually adding s1,... to the Map is ok, but that's what
// I want to avoid...
//
// Map.insert({"s1", &s1});
// ...
//
assert(&s1 == s1.This);
assert(&s2 == s2.This);
assert(&s3 == s3.This);
for (auto&& I : Map)
{
I.second->f();
}
}
As I understand it, the map will only contain valid pointers if RVO is used in auto s1 = makeS(...) etc. and this is not guaranteed.
Is there a way to deduce the template parameters while at the same time avoiding the need to manually register s1,...?
Your basic problem is you failed to implement the rule of 3. If your destructor needs non-trivial behavior (and if you register yourself in the constructor, this is the case), you must either implement or block assignment and copy construct (and/or move-assign and move-construct).
In this case, we can implement a move-construct and block move-assign, and copy construct and copy assign are implicitly blocked.
First, add name to S. Then implement a move constructor.
template <typename T>
struct S : Base
{
std::string Name;
T Func;
Base* This; // ?? why ?? this looks both dangerous and useless at the same time!
S( S&& s ): Name(std::move(s.Name)), Func(std::move(s.Func)), This(this) {
s.clear(); // technically `move` need not clear.
map[Name] = this; // overwrite
}
S& operator=(S&& s) = delete; // or implement it
now your object is moveable, and when moved it updates the Map. ~S should, I assume, unregister from Map -- detect if your name is empty (and assert at construction you gain a non-empty name), and if it is don't unregister (as you where already moved from).
Now move-construct and elided-construct have the same semantics. RVO failure results in some inefficiency, but no logical failure. Plus, your type is now moveable, which tends to be really useful.
If you need to maintain object identity, use can use std::unique_ptr:
template <typename T>
std::unique_ptr<S<T>> makeS(std::string const& name, T func)
{
return { new S<T>(name, std::move(func)) };
}
Now moving the pointer from place to place won't move the object; the pointer kept in the map will stay valid.
My suggestions to improve your code:
1) Get rid of the side effect in the constructor. Create objects in a factory method only (makeS in your code; you can make it a static member function of S) and register the S objects in that method. To disable object creation in different ways make constructor(s) private.
2) Disable S objects copying/moving and handle the objects for example as shared_ptr/unique_ptr<S> only. When you disable copying/moving you avoid the problem when your map contains a pointer to invalid objects and now you don't need to rely on RVO.
3) Use std::function<void()> instead of T Func;. In that case your class don't need to be a template class (or it will have less template arguments). That will simplify your code.

How to write a template function that can handle object or pointer function calls ?

I would like to be able to write a template function that can invoke a function call on all elements of a container. We can assume that the function name is always the same. However what isn't known is whether the container is holding objects or pointers. ie, whether I should de-reference.
template< typename TContainer >
void ProcessKeyedContainer( TContainer &keyedContainer )
{
for ( auto it = keyedContainer.begin(); it != keyedContainer.end(); ++it )
{
// do some random stuff here.
// ...
auto value = it->second;
value.Process(); // or value->Process() if the container has pointers
}
}
...
std::map< int, CMyObject > containerOfObjects;
containerOfObjects[0] = CMyObject();
std::map< int, CMyObject* > containerOfPointers;
containerOfPointers[0] = new CMyObject();
// I would like both calls to look near identical
ProcessKeyedContainer( containerOfObjects );
ProcessKeyedContainer( containerOfPointers );
Is there a neat way to be able to make the Process call inside ProcessKeyedContainer, without putting a burden on the caller ( ie the caller doesn't have to know to use it in one way for pointers and another way for objects ), and without having to duplicate too much code ?
Overloaded function template is the savior:
template<typename T>
void invoke(T * obj) //when object is pointer
{
obj->Process();
}
template<typename T>
void invoke(T & obj) //when object is non-pointer
{
obj.Process();
}
then use it as:
auto value = it->second;
invoke(value); //correct invoke() will be selected by the compiler!
But that is not good enough, as you might want to do something else also with value in the rest of the function written by you. So if you follow the above approach, there will be code duplication, as both invoke() will have almost similar code.
So here is one improvement: instead of using invoke(), turn the pointer into reference so that you could use it uniformly in your function.
template<typename T>
T& ensure_ref(T * obj) //when object is pointer
{
return *obj; //return the dereferenced object
}
template<typename T>
T& ensure_ref(T & obj) //when object is non-pointer
{
return obj; //simply return it
}
And use it as:
auto & value = ensure_ref(it->second); //call ensure_ref to ensure reference!
value.Process(); //value is gauranteed to be NOT pointer!
//you might want to do this also!
value.xyz = abc;
Hope that helps!

remove any element of vector<std::function<...>> that bound to member function

how to remove function that bound to member function of this object :
std::vector<std::function<void(int)>> callbacks;
class MyClass {
public:
MyClass() {
callbacks.push_back(
std::bind(&MyClass::myFunc,this,std::placeholders::_1)
);
}
~MyClass() {
auto it = std::remove_if( std::begin(callbacks),
std::end(callbacks),
[&](std::function<void(int)>& f) {
return // <-- this is my question
// true (remove) if f is bound to member function
// of this
});
callbacks.erase(it,std::end(callbacks));
}
void myFunc(int param){...}
};
typedef decltype(std::bind(&MyClass::myFunc,this,std::placeholders::_1)) bound_type;
auto it = std::remove_if( std::begin(callbacks),
std::end(callbacks),
[](const std::function<void(int)>& f) {
return f.target<bound_type>() != nullptr;
});
The member function template std::function::target<T> returns a pointer to the target object if it is of type T, otherwise it returns null. So you just need to be able to name the type of the target object, which you can get from decltype. Pretty simple really :-)
N.B. that will remove any callbacks of that type, not only ones that have bound the this pointer for the specific object being destroyed. If you are trying to prevent invoking callbacks on an object after it has been destroyed and have no possible way to identify which elements of the vector refer to which objects, you could consider putting a shared_ptr in your class, then storing a weak_ptr to it in the callback, which can be used to detect if the object has been destroyed:
class MyClass
{
struct NullDeleter { void operator()(void*) const { } };
std::shared_ptr<MyClass> sp;
static void safe_invoke(void (MyClass::*f)(int), const std::weak_ptr<MyClass>& wp, int i)
{
if (std::shared_ptr<MyClass> safe_this = wp.lock())
(safe_this.get()->*f)(i);
}
public:
MyClass() : sp(this, NullDeleter()) {
callbacks.push_back(
std::bind(safe_invoke, &MyClass::myFunc ,std::weak_ptr<MyClass>(sp),
std::placeholders::_1)
);
};
This wraps the call to the member function with the invoke function that converts the weak_ptr to a shared_ptr before calling the member function. If the object has been destroyed the shared_ptr will be empty, so the function does nothing. This doesn't actually remove the callback when it becomes invalid, but does make it safe to call.
You can't in the general case without a buttload of extra work. Type erasure clears this information from the object, and std::function does not expose this information directly.
Your specific example may only have one member function that could be the candidate to remove, but what about a class with 5 members that could be stored as callbacks? You'll need to test for all of them, and it's also possible to bind member functions using a lambda, which is pretty much undetectable.
Here's one solution if:
all callbacks are registered from within MyClass
the container is amended to store extra information
you're willing to do all the extra bookkeeping
std::vector<std::pair<std::function<void(int)>, void*>> callbacks;
class MyClass{
static unsigned const num_possible_callbacks = 2; // keep updated
std::array<std::type_info const*, num_possible_callbacks> _infos;
unsigned _next_info;
// adds type_info and passes through
template<class T>
T const& add_info(T const& bound){
if(_next_info == num_possible_callbacks)
throw "oh shi...!"; // something went out of sync
_infos[_next_info++] = &typeid(T);
return bound;
}
public:
MyClass() : _next_info(0){
using std::placeholders::_1;
callbacks.push_back(std::make_pair(
add_info(std::bind(&MyClass::myFunc, this, _1)),
(void*)this));
callbacks.push_back(std::make_pair(
add_info([this](int i){ return myOtherFunc(i, 0.5); }),
(void*)this));
}
~MyClass(){
using std::placeholders::_1;
callbacks.erase(std::remove_if(callbacks.begin(), callbacks.end(),
[&](std::pair<std::function<void(int)>, void*> const& p) -> bool{
if(p.second != (void*)this)
return false;
auto const& f = p.first;
for(unsigned i = 0; i < _infos.size(); ++i)
if(_infos[i] == &f.target_type())
return true;
return false;
}), callbacks.end());
}
void myFunc(int param){ /* ... */ }
void myOtherFunc(int param1, double param2){ /* ... */ }
};
Live example on Ideone.
I once needed to do something like this and I solved it by storing a vector of shared pointers of objects in the class that contain the function and remove the function from the vector by value when they are destroyed, which also makes this automatic.