C++ static member function vs lambda overhead

Viewed 85

I have some kind of templated base class

template<typename Derived>
class Base { };

and want to store derived instances of it in a list. For that I use a using derived_handle = std::unique_ptr<void, void(*)(void*) alias.

When I now add a derived instance to the list i cound use a static member function as deleter

class foo {

  template<typename Derived, typename... Args>
  void add_base(Args&&... args) {
    auto derived = derived_handle{new Base{std::forward<Args>(args)..., &foo::_deleter<Derived>};

    _derived.emplace_back(std::move(derived));
  }

private:

  template<typename Baser>
  void _deleter(void* base) {
    delete static_cast<Base*>(base);
  }

  std::vector<derived_handle> _derived{}; 

};

or a lambda

class foo {

  template<typename Derived, typename... Args>
  void add_base(Args&&... args) {
    auto deleter = [](auto* derived){
      delete static_cast<Derived*>(derived);
    }

    auto derived = derived_handle{new Base{std::forward<Args>(args)..., std::move(deleter)};

    _derived.emplace_back(std::move(derived));
  }

private:

  std::vector<derived_handle> _derived{}; 

};

Are there any advantages/disadvantages of the lambda version I should be aware of?

1 Answers

Time for a frame challenge!

You've made some bad decisions in that code. Most people who use unique_ptr, even in a polymorphic context, don't need custom deleters at all. The only reason you do, is because of your type erasure, and that's only there because Base<A> and Base<B> are unrelated types.

If you really need Base<T>, have it inherit from an actual polymorphic (and non-templated) base class with a virtual destructor. Then you don't need unique_ptr<void> (a really bad code smell), and you can actually use your list in a type-safe manner.

Related