#include #include #include using namespace System; using namespace System::Linq; using namespace System::Collections::Generic; template struct identity { using type = T; }; template struct function_of : function_of {}; template struct function_of : identity {}; template struct function_of : identity {}; template struct function_of : identity {}; template struct function_of : identity {}; template using function_of_t = typename function_of::type; template struct to_delegate; template struct to_delegate : identity> {}; template struct to_delegate : identity> {}; template struct to_delegate : identity> {}; template using to_delegate_t = typename to_delegate::type; template ref struct DelegateHelper; template ref struct DelegateHelper { using delegate_type = to_delegate_t; template DelegateHelper(F &&f) { func = new std::function(std::move(f)); } ~DelegateHelper() { this->!DelegateHelper(); } !DelegateHelper() { if (func) { delete func; func = nullptr; } } R Call(A... args) { return (*func)(std::forward(args)...); } auto ToDelegate() { return gcnew delegate_type(this, &DelegateHelper::Call); } static operator delegate_type ^ (DelegateHelper ^helper) { return helper->ToDelegate(); } private: std::function *func; }; template auto make_delegate(F &&f) { // we leak `helper`. let the GC finalize it whenever... auto helper = gcnew DelegateHelper>(std::move(f)); return helper->ToDelegate(); } void example(Func ^f) { Console::WriteLine(f(10)); } struct multiplier { int operator()(int x) { return x * k; } int k; }; int main(array ^args) { int z = 10; example(make_delegate([z](int x) { return x * z; })); example(make_delegate(multiplier{ 10 })); example(gcnew DelegateHelper([](int x) { return x; })); auto sum = make_delegate([](int a, int b) { return a + b; }); Console::WriteLine(Enumerable::Aggregate(Enumerable::Range(0, 10), sum)); Console::ReadKey(); return 0; }