C++ 从作为参数传递的函数中提取参数
我有以下功能:C++ 从作为参数传递的函数中提取参数,c++,c++builder,c++98,C++,C++builder,C++98,我有以下功能: void Class1::MainThreadFunction(const __int64 param) { if(GetCurrentThreadId() != System::MainThreadID) { RunInMainThread(MainThreadFunction, param); return; } //... } void Class2::RunInMainThread(void(__closure*
void Class1::MainThreadFunction(const __int64 param) {
if(GetCurrentThreadId() != System::MainThreadID) {
RunInMainThread(MainThreadFunction, param);
return;
}
//...
}
void Class2::RunInMainThread(void(__closure* FuncToCall)(const __int64 ParToExtract),
const __int64 fP1) {
struct {
__int64 P1;
void(__closure* F)(const __int64);
void __fastcall FTC() { F(P1); }
} Args = {fP1, FuncToCall};
TThread::Synchronize(NULL, &Args.FTC);
}
所以我试图做的是提取FuncToCall中的第一个参数,上面名为ParToExtract,用于初始化Args结构。换句话说,结构中的P1应该从名为ParToExtract的传递函数接收常量int64
上述方法可行,但作为一种解决方法,我目前将参数传递为fP1,我使用它初始化P1,但肯定有更好的方法来实现这一点
额外的好处是在RunInMainThread中有数量可变的函数参数,但目前我不得不避免使用C++11
请不要使用基于lambda或C++11的功能-这是我目前无法使用的另一个功能。由TThread::Synchronize调用的方法的签名必须与TThread method类型匹配: 所以不能直接通过它传递参数。使用lambda代替代理函数:
void MainThreadFunction(int64_t param) {
if(GetCurrentThreadId() != System::MainThreadID)
TThread::Synchronize(nullptr, [¶m]{ MainThreadFunction(param); } );
//...
}
为了获得数量可变的参数,可以将其设置为函数模板:
template< class... Args >
void MainThreadFunction(Args&&... args) {
if(GetCurrentThreadId() != System::MainThreadID)
TThread::Synchronize(nullptr, [&args...] {
MainThreadFunction(std::forward<Args>(args)...);
}
);
//...
}
在使用经典的C++11之前的编译器时,您通常会使用类私有变量来携带信息。在C++Builder的经典C++11之前的编译器中,您已经拥有的是解决这种情况的正确且唯一的方法 为了支持可变数量的参数,您必须使用多个重载,如果不深入底层内联程序集以手动设置调用堆栈,则没有其他选项,但即使如此,它也可能无法跨线程边界正常工作,例如: void Class1::mainthread函数 { 如果GetCurrentThreadId!=System::MainThreadID { RunInMainThreadMainThreadFunction; 回来 } //... } void Class1::MainThreadFunctionconst\uuu int64参数 { ifGetCurrentThreadId!=系统::MainThreadID { RunInMainThreadMainThreadFunction,参数; 回来 } //... } //根据需要等等。。。 样板 void Class2::RunInMainThreadFuncType FuncToCall { 结构{ F型; void uu fastcall FTC{F;} }Args={FuncToCall}; TThread::SynchronizeNULL,&Args.FTC; } 样板 void Class2::RunInMainThreadFuncType FuncToCall,const ParamType param { 结构{ const-ParamType&P; F型; void uu fastcall FTC{FP;} }Args={param,FuncToCall}; TThread::SynchronizeNULL,&Args.FTC; } 样板 void Class2::RunInMainThreadFuncType FuncToCall、常量ParamType1 param1、常量ParamType2 param2 { 结构{ 常数参数类型1和P1; 常数参数类型2和P2; F型; void uu fastcall FTC{FP1,P2;} }Args={param1,param2,FuncToCall}; TThread::SynchronizeNULL,&Args.FTC; } //根据需要等等。。。
如果您查看各种RTL头文件,例如sysvari.h和utilcls.h,Borland本身就是通过使用重载来解决几个自己的API中参数数量可变的问题的,有时超过30个以上的参数,这足以处理大多数用户代码。参数是函数的输入。不能从函数中提取它;您必须向函数传递一个值。@ted Lynmo不确定您是否已将my Whitesmiths样式重新格式化为K&R样式。这是个人的喜好,不应该改变,一种风格绝不优于另一种。通常我会同意,但不缩进功能体只是。。。ew.@Coder12345对不起,我从未见过这样的风格在代码审查中幸存下来,并将其误认为是一个错误。请注意,lambda方法只适用于基于Clang的编译器。在经典编译器中,结构包装器是正确的解决方案谢谢您的回答,但正如我在原始问题中提到的,我并不是在寻找lambda解决方案。在切换到支持lambdas的较新编译器之前,我必须使用一段时间的经典编译器。@Coder12345我看不到任何关于无lambda要求的提及。兰姆达斯不是我们的一部分。自C++11以来,lambda是该语言不可分割的一部分。“说得好,雷米,”他补充道。“好吧,好吧,我没有明确提到这一点。但它是C++11标准的一部分。我已经更新了这个问题。谢谢你的补充回复。是的,兰巴斯也是。你没有说没有C++11特性,你特别提到了一个标题,这个答案不需要这个标题。
template< class... Args >
void MainThreadFunction(Args&&... args) {
if(GetCurrentThreadId() != System::MainThreadID)
TThread::Synchronize(nullptr, [&args...] {
MainThreadFunction(std::forward<Args>(args)...);
}
);
//...
}