1

I want to change default_deleter for std::unique_ptr. This is quite easy to achieve, but there is one inconvenient - I have to declare variables using 2 template parameters instead of one, something like this:

std::unique_ptr<MyType, MyDeleter<MyType>> myVar;

As you may see the declaration is long and I have a feeling I can use a shorter version, but I don't know how:)

Is it possible to declare some kind of MyUniquePtr<T> that will be the same as std::unique_ptr<T, MyDeleter<T>>?

EDIT: Matthieu M. already answered, but unfortunately I can't use this feature in Visual Studio as it's not implemented. Is there other way to have this behavior?

Mircea Ispas
  • 18,498
  • 26
  • 109
  • 202

5 Answers5

8

Actually it is, using template aliases:

template <typename T>
using MyUniquePtr = std::unique_ptr<T, MyDeleter<T>>;
0x499602D2
  • 87,005
  • 36
  • 149
  • 233
Matthieu M.
  • 251,718
  • 39
  • 369
  • 642
  • 1
    Very nice feature, but I can't use this because it's not implemented in Visual Studio:( – Mircea Ispas Jun 13 '13 at 15:13
  • In this case the c++11 tag is quite disputable, since Microsoft's implementation is nowhere near complete. If you complain enough about it, maybe they'll implement this feature two releases from now. ;-P – David Foerster Jun 13 '13 at 15:19
3

If your compiler doesn't do template aliases yet, here's the C++03 idiom:

template <typename T>
struct MyUniquePtr {
    typedef std::unique_ptr<T, MyDeleter<T> > type;
};

MyUniquePtr<MyType>::type var;

The setup is uglier, but the resulting usage is almost as short: you just need to add ::type.

aschepler
  • 65,919
  • 8
  • 93
  • 144
3

Does your deleter need to be templated on the type of the object being deleted, or is it sufficient for the function call operator to be templated on the type of object being deleted?

Instead of:

template<typename T>
struct MyDeleter
{
    void operator()(T* p) const { /* ... */ }
};

Can you write:

struct MyDeleter
{
    template<typename T>
    void operator()(T* p) const { /* ... */ }
};

This, of course, depends on what state MyDeleter has to maintain.

Nevin
  • 4,205
  • 14
  • 22
0

Another way conforming to c++03 is a subclass, which unfortunately requires you to reproduce the constructors. (This can be done easier, if your compiler supports variadic template arguments, which may be the case for current MSVC.)

template <class T>
class MyUniquePtr : public std::unique_ptr< T, MyDeleter<T> > {
public:
    MyUniquePtr(args...) : std::unique_ptr< T, MyDeleter<T> >(args...) { }
};
David Foerster
  • 1,369
  • 1
  • 12
  • 22
0

You might want to consider writing your own version of a make_unique style function instead specialized for your custom allocation / deletion strategy. This also has the advantage that you can perform any specialized resource acquisition / allocation in an exception safe way. You can then declare your unique_ptr as auto and let type deduction work for you.

Community
  • 1
  • 1
mattnewport
  • 12,751
  • 2
  • 30
  • 38