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);
主->定位销();
不确定这是否是最优雅的方式,但它确实完成了我想要的工作