In78
In78

Reputation: 462

How to use std::remove_pointer with void*?

I am using std::unique_ptr in this way:

template <typename Pointer, auto deleter>
using my_unique_ptr = std::unique_ptr<std::remove_pointer<Pointer>, std::integral_constant<decltype(deleter), deleter>>;

It seems to work when Pointer = void*, but when trying to use reset on such a my_unique_ptr, I am getting this error:

invalid conversion from 'SampleType' {aka 'void*'} to 'std::unique_ptr<std::remove_pointer<void*>, std::integral_constant<...> >::pointer' {aka 'std::remove_pointer<void*>*'}

Shouldn't std::remove_pointer<void*>* automatically mean void*?

Upvotes: 0

Views: 333

Answers (1)

Guillaume Racicot
Guillaume Racicot

Reputation: 41760

Your my_unique_ptr<void*> does not contain void*. It contains a std::remove_pointer<void*>*.

Shouldn't std::remove_pointer<void*>* automatically mean void*?

The std::remove_pointer type is not magic. It's a type like any other. Here's a possible implementation:

template<typename T>
struct remove_pointer {
    using type = T;
};

template<typename T>
struct remove_pointer<T*> {
    using type = T;
};

As you can see, as you defined it, the std::unique_ptr contains a pointer to that struct, just like the compiler error mentionned.

What you probably meant to do is to use the member ::type of the struct, aka the result of the remove_pointer metafunction:

template <typename Pointer, auto deleter>
using my_unique_ptr = std::unique_ptr<typename std::remove_pointer<Pointer>::type, std::integral_constant<decltype(deleter), deleter>>;

And with C++14, there's a alias to simplify:

template <typename Pointer, auto deleter>
using my_unique_ptr = std::unique_ptr<std::remove_pointer_t<Pointer>, std::integral_constant<decltype(deleter), deleter>>;

Upvotes: 4

Related Questions