2011-11-03 62 views
5

我有一些代碼,可以大大的複雜性,通過使用lambda表達式減少。然而不幸的是,我們必須使用不完全支持C++ 11的編譯器,我們不能輕鬆切換。現在的問題是如何保持邏輯儘可能接近與不可用的功能的λ表達(即std::function是可用的,lambda表達式都沒有)。如何處理lambda表達式在拉姆達預編譯

通常的解決辦法是在其他地方定義函子,然後在適當的地方使用它:

struct functor{ 
    functor(type & member) : m_member(member) {} 
    void operator()(...) {...} 
    type & m_member; 
}; 

void function() { 
    use_functor(functor(...)); 
} 

我非常習慣這種模式,雖然我不喜歡它了很多。不定義類的主要原因通常是我將在STL中使用函數,而模板不喜歡函數內聯定義的結構。然而,在我的情況下use_functor()功能將是一個通常的方法,所以可以定義函數本身內部的算符(各函子只有一個函數內使用)。

void function() { 
    struct functor{ 
     functor(type & member) : m_member(member) {} 
     void operator()(...) {...} 
     type & m_member; 
    }; 
    use_functor(functor(...)); 
} 

這似乎有所改善,但仍需要更多的醜陋的代碼,我想。例如,我想徹底擺脫函子的名稱。我知道有可能創建一個匿名結構,如果我只使用一個值。

void function() { 
    struct{ 
     // functor(type member) : m_member(member) {} 
     void operator()(...) {...} 
     // type & m_member; 
    } callback ; 
    use_functor(callback); 
} 

但是在這一點上我不知道如何提供必要的數據成員。由於結構是匿名的,它沒有構造函數。我可以很容易地設置該成員,因爲它是公開的,但是這又會增加一條我不喜歡的線。

的目標是把它的狀態下,儘可能少地需要被改變,一旦我們切換到具有清潔lambda表達式,這將允許完全消除這一問題的編譯器。

你怎麼會去這樣做呢?

+0

當我剛發現,一些老的GCC的甚至不處理來自嵌套函數到std ::功能<>很好的結構轉換,而不會像任何的解決方案。所以我不得不使用選項一併分開邏輯。 – LiKao

回答

1

至於匿名struct的成員變量的initalisation沒有一個構造函數,你可以這樣做:

void function() { 
    type the_thing; 
    struct { 
     void operator()(...) {...} 
     type & m_member; 
    } callback = {the_thing}; 
    use_functor(callback); 
} 

callback設置type &參考m_member

0

擴大對答案的awoodland:

#define MY_LAMBDA(name, memberType, memberValue, body) \ 
    struct {          \ 
     void operator()(...) body    \ 
     memberType & memberValue;     \ 
    } name = {memberValue} 

void function() { 
    type thing_to_capture; 

    MY_LAMBDA(callback, type, thing_to_capture 
    { 
     std::cout << thing_to_capture << std::endl; 
    }); 

    use_functor(callback); 
} 

您可以使用MY_LAMBDA任何地方,你可以定義一個結構。不幸的是,如果沒有可變宏,必須將所有捕獲的對象包裝到單個對象中,並且必須在「lambda聲明」中指定該對象的類型。

另請注意,使用lambda的等效項爲:

void function() { 
    type thing_to_capture; 

    auto callback = [&thing_to_capture]() 
    { 
     std::cout << thing_to_capture << std::endl; 
    }; 

    use_functor(callback); 
} 
+0

爲了消除拼寫錯誤的機會,您可以在宏的頂部添加'type thing_to_capture;'(如果您未調用顯式c'tor或拷貝分配,如本例中所示)。 – Richard

+1

如果'MY_LAMBDA'沒有能力指定operator()'的定義,它是如何有用的? – ildjarn

+0

@ildjarn好點...編輯即將到來。 –

0

您可以嘗試提升lambda庫或boost::phoenix。它們都被設計用來進行lambda樣式操作,而不需要實際的lambda支持。由於它們是基於模板的,因此當某些事情無法按預期工作時,錯誤可能難以調試。