C++ cli 在C++/CLI向委托传递内部变量的最简单方法是什么?

C++ cli 在C++/CLI向委托传递内部变量的最简单方法是什么?,c++-cli,C++ Cli,我试图设置一个以局部变量作为参数的委托。声明如下: ref class Main { private: Func<String^>^ _expensiveMethodDelegate; public: property Func<String^>^ ExpensiveMethodDelegate { Func<String^>^ get() { return this->_expensiveMethodDeleg

我试图设置一个以局部变量作为参数的委托。声明如下:

ref class Main
{
private:
    Func<String^>^ _expensiveMethodDelegate;

public:
    property Func<String^>^ ExpensiveMethodDelegate
    {
        Func<String^>^ get() { return this->_expensiveMethodDelegate; }
        void set(Func<String^>^ value) { this->_expensiveMethodDelegate = value; }
    };

    void DoWork()
    {
        String^ result = this->_expensiveMethodDelegate();
        Debug::WriteLine(result);
    }
};
string parameter = "value";

Main main = new Main();
main.ExpensiveMethodDelegate = () =>
{
    Thread.Sleep(1000); // do expensive work
    return parameter + "1";
};

main.DoWork();
使用管理C++(VS 2015)实现这个目标的最简单方法是什么?注意:我读了一些文章,但仍然不知道解决方案是什么

我尝试过这样的代码(使用第二篇文章中的make_delegate),但编译失败:

String^ parameter = L"value";

Main^ main = gcnew Main();
main->ExpensiveMethodDelegate = make_delegate(
    [](String^ parameter) -> String^
    {
        Threading::Thread::Sleep(1000); // do work
        return parameter + L"1";
    });

main->DoWork();

这就是我想到的:

#pragma once

#include <new>

using namespace std::tr1;
using namespace System;

namespace helper
{
    private struct return_type_helper
    {
    private:

        template<class D>
        struct dependent_false { enum { value = false }; };

        template <class D>
        struct illegal_delegate_type
        {
            static_assert(dependent_false<D>::value, "Delegates with more than 2 parameters, or with parameters of tracking reference types (T%), are not supported.");
        };

        struct anything
        {
            template<class T>
            operator T() const;
        };

    public:
        template<class D>
        static decltype(static_cast<D^>(nullptr)(anything())) dummy(int(*)[2]);

        template<class D>
        static decltype(static_cast<D^>(nullptr)(anything(), anything())) dummy(int(*)[3]);
    };

    template<class Func, class Aligner = char, bool Match = (alignment_of<Func>::value == alignment_of<Aligner>::value)>
    struct aligner
    {
        static_assert(Match, "Function object has unsupported alignment");
    };

    template<class Func, class Aligner>
    private struct aligner<Func, Aligner, true>
    {
        typedef Aligner type;
    };

    template<class F>
    private ref class lambda_wrapper
    {
    public:
        lambda_wrapper(const F& f)
        {
            pin_ptr<F> pf = (interior_ptr<F>)&f_storage;
            new(pf) F(f);
        }

        ~lambda_wrapper()
        {
            pin_ptr<F> pf = (interior_ptr<F>)&f_storage;
            pf->~F();
        }

        template <class D>
        operator D ^ ()
        {
            D^ d = nullptr;
            return gcnew D(this, &lambda_wrapper<F>::invoke<decltype(return_type_helper::dummy<D>(0))>);
        }

    private:
        template<class T>
        [System::Runtime::InteropServices::StructLayout(System::Runtime::InteropServices::LayoutKind::Sequential, Size = sizeof(T))]
        value struct embedded_storage
        {
        private:
            typename aligner<T>::type dummy;
        };

        embedded_storage<F> f_storage;

        template<class R, class A1>
        R invoke(A1 a1)
        {
            pin_ptr<F> pf = (interior_ptr<F>)&f_storage;
            return (*pf)(a1);
        }

        template<class R, class A1, class A2>
        R invoke(A1 a1, A2 a2)
        {
            pin_ptr<F> pf = (interior_ptr<F>)&f_storage;
            return (*pf)(a1, a2);
        }
    };

    template <typename...>
    ref class DelegateHelper;

    template<class TParam1, class TResult>
    ref class DelegateHelper<TParam1, TResult>
    {
    private:
        Func<TParam1, TResult>^ _lambda;
        TParam1 _param1;

        TResult Execute()
        {
            return this->_lambda(this->_param1);
        }

    public:
        template<class TLambda>
        DelegateHelper(TLambda lambda, TParam1 param1)
        {
            this->_lambda = gcnew helper::lambda_wrapper<TLambda>(lambda);
            this->_param1 = param1;
        }

        static operator Func<TResult> ^ (DelegateHelper<TParam1, TResult>^ value)
        {
            return gcnew Func<TResult>(value, &DelegateHelper<TParam1, TResult>::Execute);
        }
    };

    template<class TParam1, class TParam2, class TResult>
    ref class DelegateHelper<TParam1, TParam2, TResult>
    {
    private:
        Func<TParam1, TParam2, TResult>^ _lambda;
        TParam1 _param1;
        TParam2 _param2;

        TResult Execute()
        {
            return this->_lambda(this->_param1, this->_param2);
        }

    public:
        template<class TLambda>
        DelegateHelper(TLambda lambda, TParam1 param1, TParam2 param2)
        {
            this->_lambda = gcnew helper::lambda_wrapper<TLambda>(lambda);
            this->_param1 = param1;
            this->_param2 = param2;
        }

        static operator Func<TResult> ^ (DelegateHelper<TParam1, TParam2, TResult>^ value)
        {
            return gcnew Func<TResult>(value, &DelegateHelper<TParam1, TParam2, TResult>::Execute);
        }
    };
}
#pragma一次
#包括
使用名称空间std::tr1;
使用名称空间系统;
命名空间助手
{
私有结构返回\u类型\u帮助程序
{
私人:
模板
依赖结构的_false{enum{value=false};};
模板
结构非法\u委托\u类型
{
static_assert(dependent_false::value,“不支持具有2个以上参数或跟踪引用类型(T%)参数的委托”。);
};
构造任何东西
{
模板
算子T()常数;
};
公众:
模板
静态decltype(static_cast(nullptr)(anything()))dummy(int(*)[2]);
模板
静态decltype(static_cast(nullptr)(anything(),anything()))dummy(int(*)[3]);
};
模板
结构对齐器
{
静态_断言(匹配,“函数对象具有不支持的对齐”);
};
模板
专用结构对齐器
{
typedef对准器类型;
};
模板
私有引用类lambda_包装器
{
公众:
lambda_包装(常数F&F)
{
pin_ptr pf=(内部_ptr)和f_存储;
新的(pf)F(F);
}
~lambda_wrapper()
{
pin_ptr pf=(内部_ptr)和f_存储;
pf->~F();
}
模板
运算符D^()
{
D^D=nullptr;
返回新的gcd(this,&lambda_包装器::invoke);
}
私人:
模板
[System::Runtime::InteropServices::StructLayout(System::Runtime::InteropServices::LayoutKind::Sequential,Size=sizeof(T))]
值结构嵌入式存储
{
私人:
typename对齐器::类型虚拟;
};
嵌入式存储;
模板
R调用(A1)
{
pin_ptr pf=(内部_ptr)和f_存储;
报税表(*pf)(a1);
}
模板
R调用(A1 A1、A2 A2)
{
pin_ptr pf=(内部_ptr)和f_存储;
返回(*pf)(a1、a2);
}
};
模板
ref类DelegateHelper;
模板
ref类DelegateHelper
{
私人:
Func^ u lambda;
TParam1_参数1;
TResult Execute()
{
返回此->\u lambda(此->\u参数1);
}
公众:
模板
DelegateHelper(TLambda lambda,TParam1参数1)
{
这个->\u lambda=gcnew helper::lambda\u包装器(lambda);
此->_param1=param1;
}
静态运算符Func^(DelegateHelper^值)
{
返回gcnew Func(值,&DelegateHelper::Execute);
}
};
模板
ref类DelegateHelper
{
私人:
Func^ u lambda;
TParam1_参数1;
TParam2_参数2;
TResult Execute()
{
返回此->\u lambda(此->\u参数1,此->\u参数2);
}
公众:
模板
DelegateHelper(TLambda lambda、TParam1参数1、TParam2参数2)
{
这个->\u lambda=gcnew helper::lambda\u包装器(lambda);
此->_param1=param1;
此->_param2=param2;
}
静态运算符Func^(DelegateHelper^值)
{
返回gcnew Func(值,&DelegateHelper::Execute);
}
};
}
以下是如何使用它:

String^ parameter1 = L"value1";
String^ parameter2 = L"value2";
Main^ main = gcnew Main();

auto lambda1 = [](String^ parameter) -> String^
{
    Threading::Thread::Sleep(1000);
    return parameter;
};

main->ExpensiveMethodDelegate = gcnew helper::DelegateHelper<String^, String^>(lambda1, parameter1);

main->DoWork();

auto lambda2 = [](String^ parameter1, String^ parameter2) -> String^
{
    Threading::Thread::Sleep(1000);
    return parameter1 + parameter2;
};

main->ExpensiveMethodDelegate = gcnew helper::DelegateHelper<String^, String^, String^>(lambda2, parameter1, parameter2);

main->DoWork();
String^参数1=L“value1”;
字符串^parameter2=L“value2”;
Main^Main=gcnewmain();
自动lambda1=[](字符串^parameter)->String^
{
线程::线程::睡眠(1000);
返回参数;
};
main->ExpensiveMethodDelegate=gcnew helper::DelegateHelper(lambda1,参数1);
主->定位销();
自动lambda2=[](字符串^parameter1,字符串^parameter2)->String^
{
线程::线程::睡眠(1000);
返回参数1+参数2;
};
main->ExpensiveMethodDelegate=gcnew helper::DelegateHelper(lambda2,参数1,参数2);
主->定位销();
不确定这是否是最优雅的方式,但它确实完成了我想要的工作