2015-11-03 32 views
1

我最近遇到了一個問題,需要將用lambda表達式編寫的C++ 11代碼集成到僅支持C++ 98編譯器的舊代碼庫中。我想出了一些可能的lambda類似宏,函數或函數指針等等。但看起來他們都是有限的翻譯lambda與捕獲。例如調用一個簡單的通用功能回到:可以將Lambda表達式降級爲C++ 98

template <class Fn> 
void ForEachObject(Fn fn) 
{ 
    for (uint i = 0; i < objectCount; i++) 
    { 
     fn(i, address + i * objectSize); 
    } 
} 

,典型的調用者會做一些這樣的:

uint attributes = 0x0030; 
.... 
ForEachObject([=](uint index, void * objectAddress) 
{ 
    if ((ObjectInfo(index) & attributes) != 0) 
    { 
     fn(index, objectAddress); 
    } 
}); 

注意這裏的屬性爲來自出來的λ的範圍。無論如何仍然重用沒有lambda的每個邏輯?或者我必須重新編寫每個這樣的調用者的邏輯?

+0

我不太明白你在做什麼。你只在這裏捕獲一個'uint'。您可以添加參數並使功能獨立。你想要重用什麼邏輯,如果你改變參數類型,裏面的邏輯也會改變。 – luk32

+0

你可以使用Boost嗎? – milleniumbug

+0

這是一個簡單的示例調用者,不同的調用者會將不同的局部變量傳遞到lambda範圍。在這種情況下,唯一的方法是爲lambda部分編寫獨立函數,並將這些捕獲作爲參數傳遞。對?我是lambda新手。所以只是想要如果有更好的方法來做到這一點。 – bin3377

回答

5

隨着函子:

struct Functor 
{ 
    explicit Functor(uint attributes) : attributes(attributes) {} 
    void operator() (uint index, void * objectAddress) const 
    { 
     if ((ObjectInfo(index) & attributes) != 0) 
     { 
      fn(index, objectAddress); 
     } 
    } 
    uint attributes; 
}; 

然後調用

uint attributes = 0x0030; 
// .... 
ForEachObject(Functor(attributes)); 

對於每一個不同的λ,你必須寫一個仿函數。 您不必修改ForEachObject

+0

謝謝你的回答!但問題並不是每個調用者都會使用'屬性',它只是一個示例。你是否意味着每個來電者都應該寫一個單獨的Functor來傳遞所有必要的捕獲信息? – bin3377

+0

@ bin3377是的,你爲每個lambda做一個新的Functor。這就是內部實現的方式。 –

+0

@ bin3377你可以在函數內部聲明一個函子(就在使用之前),這與使用lambda幾乎一樣簡單,而且在某些編譯器中調試更好。 –

2

能的Lamda表達被降級爲C++ 98

沒有他們做不到。先前的C++ 11標準沒有lambda語法的概念。

雖然有可像boost::lambda

代理人可以提供仿函數風格類,重寫調用運算符(<return_type> operator()(<args>);),提供同樣的效果,如在其他答覆中提到。

+1

雖然我已經投票了,但如果您可以在答案中提供一個簡短的示例,那將是一個更好的答案。 –