Feature Request: Implement std::bind-like functionality for binding member functions with state
I would like to propose the addition of a utility similar to std::bind from the C++ std. I believe it could be useful to many users as this would allow them to create custom function objects with bound arguments, providing a convenient way to adapt function signatures and pass additional data to callback functions.
A specific use case that inspired this request is a scenario where a user wants to pass stateful functions (e.g., member functions of an object) to another function, which expects a specific function signature.
Example:
Suppose we have a class MyCipher with an internal state:
class MyCipher {
public:
MyCipher(int key) : key_(key) {}
void encrypt(byte* output, const byte* input, size_t len) {
// Perform encryption with the internal key_
}
private:
int key_;
// + Other changing state
};
Now, we have a window function that needs to accept both stateful or stateless objects (to apply our cipher in byte chunks etc):
// Template function that accepts any callable object with the specified signature
template <typename Callable>
void chunkApply(byte* output, const byte* input, size_t len, Callable func) {
// ... More Logic
// Apply the function on the current chunk
func(output, currentChunk, currentChunkLength);
// ...
}
Ideally we would just do something like:
MyCipher cipher(/*blabla*/);
chunkApply(output, input, len, etl::bind(&MyCipher::encrypt, &cipher));
But currently we need to do:
// Helper Impl function with common body
template <typename Func, typename... Args>
void chunkApplyImpl(byte* output, const byte* input, size_t len, Func func, Args... args) {
// ... More Logic
// Process the data using the provided function and the additional arguments
func(output, currentChunk, currentChunkLength, args ...);
// ...
}
// Stateless version overload
void chunkApply(byte* output, const byte* input, size_t len, void (*func)(byte*, const byte*, size_t)) {
chunkApplyImpl(output, input, len, func);
}
// Stateful version overload
void chunkApply(byte* output, const byte* input, size_t len, void (*func)(byte*, const byte*, size_t, MyCipher*), MyCipher* cipher) {
chunkApplyImpl(output, input, len, func, cipher);
}
// Wrapper to adapt class function signature (in my case this is more complex)
void encryptWrapper(byte* output, const byte* input, size_t len, MyCipher* cipher) {
cipher->encrypt(output, input, len);
}
// ...
MyCipher cipher(/*blabla*/);
chunkApply(output, input, len, encryptWrapper, &cipher);
And the boiler plate increases with the number of methods we want to pass into this pattern.
I will look into what is require of std::bind.
It will depend on whether it can be implemented without access to compiler specific implicit or built-in functions.