2015-12-16 107 views
3

我甚至無法輸入示例代碼...非常丟失。這是我的原始函數,它不是一個lambda函數(我希望它是lambda)。C++如何獲得一個指向lambda函數的void指針?

static void* DoublePointer(void** arg, int arg_sz) { 
    double* n1 = In(arg[0]); 
    double* n2 = In(arg[1]); 
    double* n3 = In(arg[arg_sz-1]); 

    *n3 = *n1 + *n2; 

    return n3; 
} 

void* func_ptr = DoublePointr; //works fine 

但我真正想要的是這樣的:

my_class.save_the_func = [](void** arg, int arg_sz) { 
    double* n1 = In(arg[0]); 
    double* n2 = In(arg[1]); 
    double* n3 = In(arg[arg_sz-1]); 

    *n3 = *n1 + *n2; 

    return n3; 
} 

my_class.point_to_func = save_the_func // point_to_func is the void* member 

你有什麼需要做的,最終得到一個void *指向lambda函數?就像我說的,一個非lambda函數工作得很好。

我之所以要這樣說是因爲最終我想我的代碼看起來像這樣:

std::vector<function_entry> MyFuncEntry ={ 
add_function("MRP_DoublePointer2", "double", "double,double", "n1,n2", "add two numbers", 
    [](void** arg, int arg_sz)->void* { 
    double* n1 = In(arg[0]); 
    double* n2 = In(arg[1]); 
    double* n3 = In(arg[arg_sz-1]); 

    *n3 = *n1 + *n2; 

    return n3; 
}), 

add_function("MRP_DoublePointer3", "double", "double,double", "n1,n2", "add two numbers", 
    [](void** arg, int arg_sz)->void* { 
    double* n1 = In(arg[0]); 
    double* n2 = In(arg[1]); 
    double* n3 = In(arg[arg_sz-1]); 

    *n3 = *n1 + *n2; 

    return n3; 
}) 

}; 

換句話說,我希望定義一個函數,並在同一個地方的一些其它需要的參數。 Add_function返回一個function_entry類,它包含一些字符串和lambda函數,基本上我試圖在函數旁邊定義這些字符串,所以它更容易維護,它不在兩個不同的地方。

如果這是壞/計算昂貴,那麼我想我應該堅持使用非lambda。

這裏是我得到的錯誤: lambda error

+1

爲什麼使用'無處不在*? – Jarod42

+0

我別無選擇,我正在與另一個採用void *的軟件API進行交互,並且參數必須是void **和int。 –

+3

因爲lambda是非捕獲的,所以你應該可以在lambda前加一個一元'+'來強制它衰減到一個普通的函數指針。更多信息請訪問:http://stackoverflow.com/q/18889028/1553090 – paddy

回答

0

申報C風格的labmda功能類型名格式

return_type (*) (params)

在我們的例子

,這將是這樣的:

using my_lambda_type = void*(*)(void**, int)

現在我們聲明:

my_lambda_type my_func = [](void** args, int arg_sz)->void* { /*do stuff*/ }

您可以省略->void*自動推斷返回類型。

最後:

void* my_func_pointer = my_func;

獎金,這裏是如何定義C風格的lambda作爲一個函數參數輸入

void func_with_func_parameter(void*(*par_name_goes_here)(void**, int)) 
{ 
    //do stuff 
} 

一樣:

void func_with_func_parameter(my_lambda_type param_name_goes_here) 
{ 
    //do stuff 
} 
1

與得到一個void*指針lambda表達式的問題是,一個lambda表達式的結果是一個實際的誠實,善良的對象,不是指針對象。正如您無法將std::vectorstd::string指定爲void*一樣,您無法將lambda表達式的結果指定給void*

有趣的是,你寫的初始代碼 - 分配一個函數指針到void*--實際上並不保證編譯! C++標準在函數指針和對象指針之間進行了區分,並且它們之間不兼容。事實上,一些編譯器會直接拒絕你的代碼。

如果您需要存儲指向任意函數類型的指針,請考慮使用std::function,這是類型安全的,並且更清楚地指示您正在嘗試執行的操作。

+0

我很樂意使用std :: function,我試圖將其轉換爲'void *',我只是不知道該怎麼做! :(我知道如何使std :: function:'std :: function func_member = [](){} etc'但是在那之後我迷路了 –

+0

然後,你應該可以像調用普通函數一樣調用'func_member':'void * result = func_member(args,arg_sz);' – templatetypedef

1

你想要做的只會在某些情況下工作;最後看到警告。 Lambdas不是函數,你不能得到它們的函數指針地址。然而,你可以做的是創建一個功能和lambda一起工作。

std::function f; 
void call_f() 
{ 
    f(); 
} 

剛分配到fcall_f地址傳遞給你的API。

BIG WARNING:這甚至不是遠程線程安全的寫作。如果您在多處理環境中需要此功能,請將其保護爲任何其他一次性使用的資源。如果只有一個太熱點,你可以創建一個固定大小的函數池,但這要複雜得多。