'Determine how external memory is allocated when using a std::function object
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.
Solution 1:[1]
Is there a way to determine how the external memory of a
std::functionobject 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_wrapper = new (memory) Wrapper<T>(t);
}
~Function()
{
m_wrapper->~Wrapper(); // destructor needs to be called explicitly
// free the memory of m_wrapper according to your personal
// allocation strategy
}
void operator()()
{
(*m_wrapper)();
}
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...
Solution 2:[2]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Jakob Stark |
