Is there a way to determine how the external memory of a std::function
object is allocated? std::function
might not allocate external memory if it is feed with a raw C function pointer, but it might get a std::bind()
object, and it is not prepared to store copied std::function
objects of any size, so it has to allocate external memory in this case.
CodePudding user response:
Is there a way to determine how the external memory of a
std::function
object is allocated?
No, there isn't – at least not any more (since C 17), see comments to question.
I need function<>-objects because they can store a whole callable object with its contents, in case of a bind()-object the parameters for it.
Well, you can always re-write standard templates and modify their behaviour in a manner that suits your own needs. What about a template class that copies the target (e.g. the bind
object) and provides an operator()
that itself calls the bind
object? You can provide your own memory management there then:
class Function
{
class WrapperBase
{
virtual ~WrapperBase() { }
virtual void operator()() = 0; // with appropriate return type
// and parameters – you could make
// Function a template for
};
template <typename T>
class Wrapper
{
T m_t;
public:
Wrapper(T& t) : m_t(t) { }
void operator()() override
{
m_t();
}
};
public:
template <typename T>
Function(T& t)
{
void* memory = nullptr; // your personal memory allocation instead
// consider correct size and alignment!
m_t = new (memory) Wrapper<T>(t);
}
~Function()
{
m_t->~Wrapper(); // destructor needs to be called explicitly
// free the memory of m_t according to your personal allocation strategy
}
void operator()()
{
(*m_t)();
}
private:
WrapperBase* m_wrapper;
};
The example is incomplete, not considering const-ness of T
, move construction etc. – you might want to add on your own.
You might want to avoid copying entirely and just store references – or specialise the templates such that objects received by normal references are stored as references only while objects received by rvalue references are copied. Endless possibilities...
CodePudding user response:
Allocator support for std::function
was deprecated for C 17 and not well supported by the libraries before C 17.
cppreference for example says:
std::function's allocator support was poorly specified and inconsistently implemented. Some implementations do not provide overloads (6-10) [these are the constructors with allocator support] at all, some provide the overloads but ignore the supplied allocator argument, and some provide the overloads and use the supplied allocator for construction but not when the std::function is reassigned. As a result, allocator support was removed in C 17.
The corresponding proposal with a more detailed explanation has been given in the comments to your question by @unddoch.
So I am afraid, that the answer to your question is no. There is no allocator support in std::function
.