Home > front end >  Function that accepts any pointer type
Function that accepts any pointer type

Time:10-26

I have a function void Foo(MyType* mt). I want callers to be able to pass any pointer type to this function (e.g. unique_ptr, shared_ptr or iterator) and not require passing a raw pointer. Is there any way to express this? I could write:

template <typename T>
void Foo(T t);

This will work since it will only compile if T supports operator-> and operator* which I use inside Foo, it will also only work if T has the same interface as MyType but it seems wrong to not specify in the API that I expect that template argument to be a pointer to MyType. I could also write my own wrapper:

template <typename T>
class PointerWrapper {
 public:
  PointerWrapper(T* t) : raw_ptr(t) {}
  PointerWrapper(const std::unique_ptr<T>& t) : raw_ptr(t.get()) {}
  ...
 private:
  T* raw_ptr;
};

void Foo(PointerWrapper<MyType> mt);

This seems clunky because I will need to extend PointerWrapper for every smart pointer type under the sun.

Is there an accepted way to support this?

CodePudding user response:

In C 20, you'd write a concept such as

template <typename P, typename T>
concept points_to = requires(P p) {
    { *p } -> std::common_reference_with<T &>
} && std::equality_comparable_with<std::nullptr_t>

template <points_to<MyType> T>
void Foo(T t);

Prior to that, you could write something involving std::pointer_traits

template <typename T>
std::enable_if_t<std::is_same_v<MyType, typename std::pointer_traits<T>::element_type>> Foo(T t);

CodePudding user response:

I want callers to be able to pass any pointer type to this function (e.g. unique_ptr, shared_ptr or iterator

Don't.

Each kind of smart (or dumb) pointer has a very specific purpose, illustrated below.

void foo(std::shared_ptr<T>);  // I will assume joint ownership 
                               // that may or may not outlive the call

void foo(std::unique_ptr<T>);  // I will take your ownership away
                               // You better not be needing it anymore

void foo(T*);                  // I am just borrowing it
                               // Whoever owns it should not worry

It makes little sense for a function to either take ownership or not, depending on what kind of pointer the user passes.

And, naturally, if your function does not do any iterating things, it should not take iterators.

  •  Tags:  
  • c
  • Related