Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从作为参数传递的函数中提取参数_C++_C++builder_C++98 - Fatal编程技术网

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, [&param]{ 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)...); 
            }
        );
    //...
}