I'm working on a resource management class and want to have the user provide a functor to a "ReleaseResource" method as part of the resource manager's constructor. From there when a resource is requested that functor will be provided as the deleter for the shared_ptr that I will be returning so that the appropriate method will be called when the resource is no longer used.
The problem I'm running into that this requires me to store the functor in my class, and I'm not entirely sure how to do that. Typically when using a functor you template the function like so:
template<class MyFunctor> MyMethod(MyFunctor f) {
f();
}
Which is great if you intend to use the functor in the scope of that function, but since the template goes out of scope with the function I'm not sure how you would specify a variable of the appropriate type to store the functor for later use.
Can anyone point me in the right direction here?
template<class MyFunctor> MyMethod(MyFunctor f) {
boost::function<void()> g = f;
g();
}
The type you pass to boost::function is the function type. For example, int(bool, char) is the type of a function returning int and taking a bool and a char. That said, if you want to construct the shared_ptr right away, you don't need to store the functor somewhere (boost::function requires the new operator for that, even though for very small functors, it will use special tricks to only use stack allocation (small buffer optimization)):
template<class MyFunctor> MyMethod(MyFunctor f) {
boost::shared_ptr<T> ptr(new T, f);
}
boost::function is part of tr1 and will be part of the next official C++ Standard. Example:
struct Manager {
template<typename Deleter>
Manager(Deleter d)
:deleter(d) {
}
boost::shared_ptr<Resource> allocate() {
...
return boost::shared_ptr<Resource>(resource, deleter);
}
private:
boost::function<void(Resource *)> deleter;
};
There are two ways, both of which biol down to templating the class.
template <MyFunctor>
class MyClass
{
MyFunctor func;
public:
MyClass(MyFunctor f) :func(f)
{ }
MyMethod()
{
func();
}
}
This would require you to know the type of the functor. To avoid that, we can use a factory:
template<MyFunctor>
MyClass<MyFunctor> MakeFunctorClass(MyFunctor f)
{
return MyClass<MyFunctor>(f);
}
Alternately, since in all likelihood, most of the functor signature will be the same, with only a small part changing, we could use that:
template <MyType>
class MyClass
{
typedef std::binary_function<MyType, MyType, bool> MyFunctor;
MyFunctor func;
public:
MyMethod(MyFunctor f)
{
func = f;
func();
}
}
This makes usage a bit simpler:
bool AreEqual(int, int);
MyClass<int> myc;
myc.MyMethod(AreEqual);
at the expensive of a trickier definition (i.e., I don't guarantee that the binary_function typedef I gave will work)
Not sure if this would help, but be aware that boost::shared_ptr has constructor overrides which allow the user to include a custom de-allocation (and custom allocator, if desired). This might be sufficient for what you need (it's designed with that in mind, if I'm reading your use-case correctly).
Related
Is there a class in standard library that will invoke provided function in its destructor?
Something like this
class Foo
{
public:
template<typename T>
Foo(T callback)
{
_callback = callback;
}
~Foo()
{
_callback();
}
private:
std::function<void()> _callback;
};
auto rai = Foo([](){ cout << "dtor";});
there is an experimental scope_exit
example: https://godbolt.org/z/4r54GYo33
You can use std::shared_ptr for that.
std::shared_ptr<void>(nullptr, [](void*){ std::cout << "dtor\n";});
See it online.
std::shared_ptr calls deleter even if managed pointer is nullptr, so there's no need to use any dummy pointer in there. However, personally I'd have strong concerns agains (ab)using std::shared_ptr in this way and I'd probably not let it through review. It's one big gotcha (although it may become an idiom if it's used all over a project).
for implement it, I'd suggest not use type-erased std::function.
here is a possible implementation
template<typename F>
struct scope_exit{
[[nodiscard]]
scope_exit(F&& f):f(std::move(f)){}
~scope_exit(){f();}
scope_exit(const scope_exit&)=delete;
scope_exit& operator=(const scope_exit&)=delete;
F f;
};
I want to create a guard, which locks a function on construction and unlocks it on destruction, e.g. calling the function with false and true.
class A {
void enable( bool flag );
};
within another method, I want to use:
A::anotherMethod( ... ) {
block_guard(A::enable); // now A::enable(false)
// some operation
} // now A::enable(true)
my ideas:
using template
template < class T >
class block_guard {
T t_;
public:
block_guard( T& t ) : t_(t) {
t_(false);
}
~block_guard() {
t_(true);
}
};
the question is, how to instantiate the template? maybe with boost::bind?
using boost::function
class block_guard {
typedef boost::function< void (bool) > T;
T t_;
public:
block_guard( T& t ) : t_(t) {
t_(false);
}
~block_guard() {
t_(true);
}
};
this works fine, but the call seems to be very complicated with
block_guard bg(boost::function< void (bool) >(boost::bind(&A::enable, pointer-to-A, _1));
any ideas?
maybe there is another, much simpler way?
First, realize that the member function is not all you need; you also need the object to invoke it on. There is no way in C++ for an object created in a function to implicitly capture the current this pointer.
I'm going to assume you don't have C++11 available. If you do, using your second solution with a lambda expression is easiest.
Now, if you don't care about the slight performance hit of boost::function (and you shouldn't), the second solution is good, but I would modify it slightly to make it more convenient to use by pulling the bind into the constructor.
class block_guard {
typedef boost::function< void (bool) > block_fn;
block_fn block_fn_;
public:
// For non-member functions and function objects:
template <typename Fn>
block_guard(Fn fn) : block_fn_(fn) {
block_fn_(false);
}
// For member functions:
template <typename T, typename Ret>
block_guard(T* obj, Ret (T::*fn)(bool)) : block_fn_(boost::bind(fn, obj, _1)) {
block_fn_(false);
}
~block_guard() {
block_fn_(true);
}
};
Usage:
block_guard guard(this, &A::enable);
I use a Ret parameter here because there's no reason not to allow functions that return something - the return value will simply get ignored.
If you don't want boost::function, the thing will get less easy to use, because you have to template the block guard. It becomes useful to make a block_guard specifically for member functions then. You also lose the ability to use non-void functions.
template <typename T>
class block_guard {
typedef void (T::*block_fn)(bool);
T* obj_;
block_fn block_fn_;
public:
block_guard(T* obj, block_fn fn) : obj_(obj), block_fn_(fn) {
(obj_->*block_fn_)(false);
}
~block_guard() {
(obj_->*block_fn_)(true);
}
};
Usage:
block_guard<A> guard(this, &A::enable);
Yes, there is a much simpler way, forget templates, generic thing and whatever not necessary and focus on the task.
All you need is a class with a ctor and a dtor. Write the dtor first, it reveals what you will need to work. Then write the ctor, taking arguments as needed. Lastly make the unwanted functions deleted (cctor, op=). Done.
Not generic, but straight to the point.
I would like to pass (shared) ownership of an object to a function foo::bar.
The thing is I do not care, whether the ownership is exclusive or shared.
I see class foo as an interface where I do not want to care about the ownership details.
All I care about is that I can secure the lifetime of the passed smart pointer beyond the return of foo::bar.
Now I could write
class foo {
void bar( std::shared_ptr<blub> );
void bar( std::unique_ptr<blub> );
};
but this is unelegant in times where we have accumulated several smart pointer variants.
And writing an overload for every variant is quite cumbersome, especially if I want to use this scheme multiple times in my code.
Now I also do not want foo to be templated, for the obvious template complexities.
The simplest I can come up with would be a smart pointer wrapper
template <typename T>
class owning_ptr {
// Sorts out the largest type so we can allocate enough space
typedef largest<std::shared_ptr<T>, std::unique_ptr<T>, myptr<T>>::type big_type;
typedef std::aligned_storage <sizeof(big_type), std::alignment_of<big_type>::value>::type buffer_type;
buffer_type _internal;
int _type;
};
which is a bit inefficient. Is there a better way to construct the wrapper?
In the end I would really like to have the signature:
class foo {
void bar( owning_ptr<blub> );
};
Note: There's an interesting EDIT at the bottom
If you don't want to parameterize or overload on the owning pointer type, you're probably best off taking a shared_ptr<> and forcing a conversion for unique_ptr<>. Any non-template solution I can think of would have at least the same amount of overhead as a shared_ptr, most requiring a polymorphic call, a free-store allocation, or both.
You might be able to automate the conversion from shared_ptr by taking some type of proxy converter, which should allow you to take either a unique_ptr R-value or a shared_ptr without a cast or explicit conversion (other than move()) and extract a usable shared_ptr to store in your instance. Here's an example:
#include <iostream>
#include <memory>
#include <utility>
using namespace std;
// Take an instance of gimme_owned_ptr<T> to save off a shared_ptr<T>
// from either a shared_ptr or unique_ptr.
template<typename T>
struct gimme_owned_ptr {
// Make the two constructors templates so we can accept
// any convertible owning pointer:
template<typename S>
gimme_owned_ptr( unique_ptr<S> p )
: p_( shared_ptr<S>( move(p) ) )
{ }
template<typename S>
gimme_owned_ptr( shared_ptr<S> p )
: p_( p )
{ }
shared_ptr<T> get() const {
return p_;
}
private:
shared_ptr<T> p_;
};
struct Foo {
void operator()() const { v_call(); }
virtual ~Foo() { }
private:
virtual void v_call() const = 0;
};
struct Bar {
Bar( gimme_owned_ptr<Foo const> const &gop )
: foo_( gop.get() )
{ }
void operator()() const { (*foo_)(); }
private:
shared_ptr<Foo const> foo_;
};
struct Baz : Foo {
private:
virtual void v_call() const { cout << "Baz()()\n"; }
};
int main() {
unique_ptr<Baz> upf( new Baz() );
shared_ptr<Baz> spf( new Baz() );
Bar upb( move( upf ) );
Bar spb( spf );
upb();
spb();
}
Yes, this solution does use templates, but only for the gimme_owned_ptr utility class template, and only for re-use and conversion. Your own class (Bar in this case) wouldn't need to be a template, nor would you need to re-implement gimme_owned_ptr to use it with another type.
======== EDIT ========
I just checked, and the built-in conversion from unique_ptr to shared_ptr essentially does everything the gimme_owned_ptr class I wrote above. If the class takes a type of shared_ptr<T>, passing a move(unique_ptr<S>) will result in a workable conversion. So, all you really need is to take a shared_ptr and the only thing the user should have to do is call move() on unique_ptrs (which they should be doing anyway). The only reason to use something like gimme_owned_ptr would be to accept a different mixture of pointers or accept them in a different way. (For example, you could make the move() unnecessary by taking a unique_ptr<S>& and calling move() internally, but this is probably a bad idea as it will silently seize ownership.)
Suppose I have a class template which have a member pData, which is an AxB array of arbitary type T.
template <class T> class X{
public:
int A;
int B;
T** pData;
X(int a,int b);
~X();
void print(); //function which prints pData to screen
};
template<class T>X<T>::X(int a, int b){ //constructor
A = a;
B = b;
pData = new T*[A];
for(int i=0;i<A;i++)
pData[i]= new T[B];
//Fill pData with something of type T
}
int main(){
//...
std::cout<<"Give the primitive type of the array"<<std::endl;
std::cin>>type;
if(type=="int"){
X<int> XArray(a,b);
} else if(type=="char"){
X<char> Xarray(a,b);
} else {
std::cout<<"Not a valid primitive type!";
} // can be many more if statements.
Xarray.print() //this doesn't work, as Xarray is out of scope.
}
As the instance Xarray is constructed inside of an if statement, I cannot use it anywhere else. I tried to make a pointer before the if statements but as the type of the pointer is unknown at that point, I did not succeed.
What would be a proper way of dealing with this kind of a problem?
The problem here is that X<int> and x<char> are completely unrelated types.
The fact that they are both a result of the same templated class won't help here.
I can see several solutions, but those depends on what you really need.
You could, for instance make the X<> instances derive from a common non-templated base class that has the print() method (eventually as a pure virtual). But before you do that, be sure that it makes sense on a functional level: one should use inheritance because it makes sense, not solely because of technical constraints. And if you do that, you probably will want to have a virtual destructor as well.
You could also bind and store a std::function<void ()> to the method you want to call, but ensure that the objects are still "alive" (they aren't in your current code: both the X<int> and X<char> are destroyed when they go out of scope, way before you actually call print()).
A final solution would be to make some variant type that is compatible with both X<int> and X<char> (boost::variant<> can help here). You could then write a visitor that implements the print() functionality for each type.
Picking the last solution, it would become something like:
typedef boost::variant<X<int>, X<char>> genericX;
class print_visitor : public boost::static_visitor<void>
{
public:
template <typename SomeType>
void operator()(const SomeType& x) const
{
// Your print implementation
// x is your underlying instance, either X<char> or X<int>.
// You may also make several non-templated overloads of
// this operator if you want to provide different implementations.
}
};
int main()
{
boost::optional<genericX> my_x;
if (type=="int") {
my_x = X<int>(a,b);
} else if(type=="char") {
my_x = X<char>(a,b);
}
// This calls the appropriate print.
if (my_x) {
boost::apply_visitor(print_visitor(), *my_x)
}
}
We actually lack the knowledge to give a definitive answer: if your classes are "entities", then you probably should go for inheritance. If they are more like "value classes", then the variant way might be more suited.
C++ is a statically typed language, meaning that you must know the type of objects at compile time. In this case you are basing the type of the object constructed on user input, so it's not possible to know the type at runtime.
The most common way to address this issue is to use dynamic polymorphism in which functions are invoked via a common interface using late binding. We accomplish this in C++ using virtual functions. For example:
struct IPrintable {
virtual void print() = 0;
};
template<class T>
class X : public IPrintable {
// Same code as you showed above.
};
int main() {
std::cout<<"Give the primitive type of the array"<<std::endl;
std::cin>>type;
std::unique_ptr<IPrintable> XArray;
if(type=="int"){
XArray.reset(new X<int>(a,b));
} else if(type=="char"){
XArray.reset(new X<char>(a,b));
} else {
std::cout<<"Not a valid primitive type!";
} // can be many more if statements.
Xarray->print() // this works now!
}
This solves the out of scope issue and allows you to print using the dynamic type of the XArray variable. Virtual functions are the secret sauce that make this possible.
Rather than trying to fit the templates into main I would go the opposite way than the rest of the suggestions... move the code out of main and into it's own (possibly templated) function that needs to deal with a single type:
template <typename T>
void generateAndPrint(int a, int b) {
X<T> x(a,b);
x.print();
}
int main() { ...
if (type=="int") generateAndPrint<int>(a,b);
else if (type=="char") generateAndPrint<char>(a,b);
else ...
}
If you want to work with different arrays, whatever their type, templates alone cannot help you. Currently, there is exactly no relationship between X<int> and X<char>.
If you want to treat them as two subtypes of a common type, you will have to use inheritance (and dynamically allocated variables). For instance, all X<T> may inherit the same base class, say Printable, and you can store the data in a unique_ptr<Printable>:
unique_ptr<Printable> r;
if(type=="int"){
r.reset(new X<int>(a,b));
} else if(type=="char"){
r.reset(new X<char>(a,b);
}
r->print();
But this is probably not the best design.
A probably better solution would be, instead of trying to work outside of the if, to move all the work inside of the if. In your simple example, this could be done by duplicating the call to print, but this is not pretty nice either. But, going toward this idea, we can create a template function that does the job:
template<class T>
void workWithType(int a, int b)
{
X<T> Xarray(a, b);
Xarray.print();
}
//...
if(type=="int"){
workWithType<int>(a,b);
} else if(type=="char"){
workWithType<char>(a,b);
}
I want to have a run-time interface that offers some creation methods. These methods return unique_ptr<T>, and I want to enable custom deletion by the creating class. The thing is that I definitely don't want the interface to offer these methods directly- they should only be available in the destruction of the unique_ptr<T, SomeCustomDel>. Now, I figured that I can use std::unique_ptr<T, std::function<void(T*)>>, but I'd really rather not because I simply don't need that level of abstraction and I don't want to have to pay the heap allocation.
Any suggestions?
Your specification isn't completely clear to me, but have you considered unique_ptr<T, void(*)(void*)>? This is a very flexible type with many qualities of a dynamic deleter.
If that isn't what you're looking for, you might try something along the lines of:
class impl
{
public:
virtual ~impl();
virtual void operator()(void*) = 0;
virtual void other_functionality() = 0;
};
class my_deleter
{
impl* p_;
public:
...
void operator()(void* p) {(*p_)(p);}
void other_functionality() {p_->other_functionality();}
...
};
It is difficult to know what is best in your case without more details about your requirements.
I wish there was a standard "dynamic" deleter version of std::unique_ptr. This mythical class would allow me to attach a deleter to the unique_ptr when I instantiate it, similar to std::shared_ptr.
That said if such a type existed I suspect it would essentially be implemented with std::unique_ptr<T,std::function<void(T*)>>. The very thing you wanted to avoid.
However I think you're underestimating std::function. Its implementation is optimization to avoid hitting the heap if possible. If your deleter object remains small everything will be done on the stack (I think boost::function can statically handle deleters up to 32 bytes in size).
A for the problem of a too general deleter. You have to provide the definition of the deleter. There is no way around that. However you don't have to let the user instantiate the class, which essentially forbids them from using it. To do this make the deleter's constructor(s) require a tag structure that is only defined in the implementation file.
Or possibly the simplest solution. Put the deleter in a detail namespace. The user is still free to use it, but it's obvious that they should not and can't complain when you change it, breaking their code.
I see two options.
Option 1: Use a custom deleter that contains a function pointer and optionally a raw char array to encode some state if necessary:
template<class T>
void simply_delete(T* ptr, const unsigned char*) {
delete ptr;
}
template<class T, int StateSize>
struct my_deleter {
void (*funptr)(T*,const unsigned char*);
array<unsigned char,StateSize> state;
my_deleter() : funptr(&simply_delete<T>) {}
void operator()(T* ptr) const {
funptr(ptr,StateSize>0 ? &state[0] : nullptr);
}
};
template<class T>
using upi = unique_ptr<T,my_deleter<T,sizeof(void*)>>;
Now, you can create different upi<T> objects that store different function pointers and deleter states without the need of mentioning what exactly is happening in its type. But this is almost the same as a function<> deleter which implements the "small function optimization". You can expect a decent standard library implementation to provide a very efficient function<> wrapper for small function objects (like function pointers) that don't require any heap allocations. At least I do. :)
Option 2: Simply use shared_ptr instead of unique_ptr and make use of its built-in type erasure feature with respect to deleters. This will also allow you to support Derived->Base conversions easily. For greatest control over what is allocated where you could use the std::allocate_shared function template.
This is a response to one of the answers, not to the original question. It is an answer instead of a comment simply because of formatting reasons.
I wish there was a standard "dynamic"
deleter version of std::unique_ptr.
This mythical class would allow me to
attach a deleter to the unique_ptr
when I instantiate it, similar to
std::shared_ptr.
Here is a start of an implementation of such a class. It is fairly easy to do. I've used unique_ptr only as an exception safety aid, nothing more. It is not as full-featured as you might like. These extra features are left as an exercise for the reader. :-) What is below establishes unique ownership of the pointer and storage for the custom dynamic deleter. Note that the smart pointer owns a passed-in pointer even if the constructor of the smart pointer throws (this is actually where unique_ptr is most useful in the implementation).
#include <memory>
#include <type_traits>
namespace detail
{
class impl
{
public:
virtual ~impl() {};
};
template <class T, class D>
class erase_type
: public impl
{
T* t_;
D d_;
public:
explicit erase_type(T* t)
noexcept(std::is_nothrow_default_constructible<D>::value)
: t_(t)
{}
erase_type(T* t, const D& d)
noexcept(std::is_nothrow_copy_constructible<D>::value)
: t_(t),
d_(d)
{}
erase_type(T* t, D&& d)
noexcept(std::is_nothrow_move_constructible<D>::value)
: t_(t),
d_(std::move(d))
{}
virtual ~erase_type()
{
if (t_)
d_(t_);
}
erase_type(const erase_type&) = delete;
erase_type& operator=(const erase_type&) = delete;
};
} // detail
template <class T>
class my_pointer
{
T* ptr_;
detail::impl* impl_;
public:
my_pointer() noexcept
: ptr_(nullptr),
impl_(nullptr)
{}
template <class Y>
explicit my_pointer(Y* p)
: ptr_(static_cast<T*>(p)),
impl_(nullptr)
{
std::unique_ptr<Y> hold(p);
impl_ = new detail::erase_type<Y, std::default_delete<Y>>(p);
hold.release();
}
template <class Y, class D>
explicit my_pointer(Y* p, D&& d)
: ptr_(static_cast<T*>(p)),
impl_(nullptr)
{
std::unique_ptr<Y, D&> hold(p, d);
typedef
detail::erase_type<Y, typename std::remove_reference<D>::type>
ErasedType;
impl_ = new ErasedType(p, std::forward<D>(d));
hold.release();
}
~my_pointer()
{
delete impl_;
}
my_pointer(my_pointer&& p) noexcept
: ptr_(p.ptr_),
impl_(p.impl_)
{
p.ptr_ = nullptr;
p.impl_ = nullptr;
}
my_pointer& operator=(my_pointer&& p) noexcept
{
delete impl_;
ptr_ = p.ptr_;
impl_ = p.impl_;
p.ptr_ = nullptr;
p.impl_ = nullptr;
return *this;
}
typename std::add_lvalue_reference<T>::type
operator*() const noexcept
{return *ptr_;}
T* operator->() const noexcept
{return ptr_;}
};
Note that unlike unique_ptr (and like shared_ptr), the constructors taking a pointer are not noexcept. Although that could possibly be mitigated via the use of a "small deleter" optimization. Yet another exercise left for the reader. :-)
I found this question googling my own problem; using unique_ptr with an abstract base class pointer. All the answers are great. I found #deft_code's one to be the best for my needs.
This is what I ended up doing in my case:
Suppose T is an abstract base class type. The makeT(), func creates a new instance of some derived class, and returns the T*:
std::unique_ptr<T, std::function<void(T*)>> p(makeT(), [](T* p){p.delete();});
I just wanted to share this for those who are looking for short, copy and pasteish solution.
For the untrained c++11 eyes, the [](... syntax is a lambda.
As is mentioned in the other answers, it's not a 'function pointer' in the C sense, but a callable c++ object, which is really tiny, and should have negligible overhead to carry it around.