Skip to content

Instantly share code, notes, and snippets.

@Nekrolm
Created November 2, 2024 15:20
Show Gist options
  • Save Nekrolm/28b4c398d75e001afb9306853cb75642 to your computer and use it in GitHub Desktop.
Save Nekrolm/28b4c398d75e001afb9306853cb75642 to your computer and use it in GitHub Desktop.
std::function type erasure example
#include <stdlib.h>
#include <cstdint>
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <functional>
#include <utility>
#include <memory>
struct Addition {
static int operator() (int x, int y) {
return x + y;
}
};
struct ModAddition {
int mod;
int operator() (int x, int y) {
return (x + y) % mod;
}
};
template <typename RetVal, typename... Args>
struct MyFunction {
public:
RetVal operator () (Args... args) {
return (*impl_)(args...);
}
template <typename F>
MyFunction(F&& func) : impl_ {
[&]() {
struct FunctionImpl final : public FunctionBase {
std::decay_t<F> impl_;
FunctionImpl(decltype(func) init) : impl_{std::forward<decltype(init)>(init)} {}
RetVal operator()(Args... args) override {
return impl_(args...);
}
};
return std::make_unique<FunctionImpl>(std::forward<F>(func));
}()
}{}
private:
struct FunctionBase {
virtual ~FunctionBase() = default;
virtual RetVal operator()(Args...) = 0;
};
std::unique_ptr<FunctionBase> impl_;
};
int main() {
// {
// std::function<int(int, int)> operation = Addition {};
// std::cout << operation(5, 10) << "\n";
// operation = ModAddition { 10 };
// std::cout << operation(6, 6) << "\n";
// }
// // std::cout << "----------\n";
{
MyFunction<int, int, int> operation = Addition {};
std::cout << operation(5, 10) << "\n";
operation = ModAddition { 10 };
std::cout << operation(6, 6);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment