An easy way to implement a small buffer optimization for erasing an arbitrary type (for example, in std :: function.)

I often use the style erase technique. Usually it looks like this:

class YetAnotherTypeErasure
{
public:
   // interface redirected to pImpl
private:
   // Adapting function
   template ...
   friend YetAnotherTypeErasure make_YetAnotherTypeErasure (...);

   class Interface {...};

   template <typename Adaptee>
   class Concrete final : public Interface { 
     // redirecting Interface to Adaptee
   };

   std::unique_ptr<Interface> pImpl_; // always on the heap
};

std::functiondoes something similar, but has a slight buffer optimization, so if it is Concrete<Adaptee>smaller than smth and has nothrow move operations, it will be stored in it. Is there any general library solution to make this pretty easy? To ensure that only a small buffer is saved at compile time? Maybe something was suggested for standardization?

+6
source share
3 answers

I found a pretty good solution for everyday code - use std :: function

, , 20 : https://gcc.godbolt.org/z/GtewFI

0

, , .

, , (, std::aligned_storage). , .

( ) any . libstd++ std::experimental::any , ( __, , ).

. ( , - any). , .

+3

, c++ 20 polymorphic_value , c++: wg21.link/p0201

Essentially, it's like std :: any, but all your types must inherit the same interface. This is a semi-regular; they decided to drop equality.

This has some overhead: one vptr in the class itself and a separate dispatch mechanism in a polymorphic value. It also has a pointer type interface instead of a type value.

However, given how easy it is to use compared to writing your own type_erased adapter, I would say that for most cases it is more than enough.

0
source

Source: https://habr.com/ru/post/1614848/


All Articles