2012-09-28 28 views
28

我在網上閱讀關於封閉。我想知道C++是否有內置的閉包工具,或者有什麼方法可以用C++實現閉包?我們有C++中的閉包嗎?

+3

除了下面的答案,還請查閱http://en.cppreference.com/w/cpp/language/lambda更多的參考頁面。 –

+0

顯然很多人仍然將匿名函數與閉包混合在一起。如果C++ 11確實支持閉包,或者只是匿名函數(「lambdas」),我仍然不清楚。我不希望C++支持與JavaScript,Python,Scala和其他人一樣的實際閉包,會發現它非常令人驚訝。 – dividebyzero

+1

證明自己錯了,是的,它捕獲上下文中的變量,通過複製,甚至通過引用,顯然,唯一的怪癖是沒有垃圾收集...仍然想更好地理解如何在實踐中的所有作品http:// en.cppreference.com/w/cpp/language/lambda – dividebyzero

回答

6

是的,C++ 11封名爲lambdas

在C++ 03中沒有對lambda表達式的內置支持,但有Boost.Lambda實現。

5

我懷疑這取決於你的封閉是什麼意思。我一直使用的含義是 意味着某種類型的垃圾回收(儘管我認爲它可以使用引用計數來實現)。不像在其他 語言lambda表達式,其捕獲的引用,並保持被引用的對象 活着,C++ lambda表達式任一捕獲的值,或者該對象refered到是 保持活動(和基準能夠容易地吊着)。

12

如果你明白封閉物,以具有嵌入的,持久的,隱藏的,不可分離上下文(內存狀態)函數的引用,比是:

class add_offset { 
private: 
    int offset; 
public: 
    add_offset(int _offset) : offset(_offset) {} 
    int operator() (int x) { return x + offset; } 
} 

// make a closure 
add_offset my_add_3_closure(3); 

// use cloure 
int x = 4; 
int y = my_add_3_closure(x); 
std::cout << y << std::endl; 

下一個修改它的狀態:

class summer 
{ 
private: 
    int sum; 
public: 
    summer() : sum(0) {} 
    int operator() (int x) { return sum += x; } 
} 

// make a closure 
summer adder; 
// use closure 
adder(3); 
adder(4); 
std::cout << adder(0) << std::endl; 

內部狀態不能從外部引用(訪問)。

根據您如何定義它,閉包可以包含對多個函數的引用,或者兩個閉包可以共享相同的上下文,即兩個函數可以共享相同的持久狀態。

閉合意味着不包含自由變量 - 它與只有私有屬性和只有公共方法的類相當。

+3

行爲與封閉類似,但我不會說它是封閉。 – Setepenre

+0

@Stepenre會有什麼不同? – Zrin

+2

這幾乎看起來像一個閉包,你在這裏只是一個持有一個方法修改狀態的對象,加上一些語法糖,因爲它是「operator()」,而不是其他任何方法。讓它返回一個取決於狀態或方法參數的lambda,然後我們正在說話。 – dividebyzero

6

是的,這顯示瞭如何在不使用仿函數的情況下實現具有狀態的函數。

#include <iostream> 
#include <functional> 


std::function<int()> make_my_closure(int x){ 
    return [x]() mutable { 
     ++x; 
     return x; 
    }; 
} 

int main() 
{ 
    auto my_f = make_my_closure(10); 

    std::cout << my_f() << std::endl; // 11 
    std::cout << my_f() << std::endl; // 12 
    std::cout << my_f() << std::endl; // 13 

    auto my_f1 = make_my_closure(1); 

    std::cout << my_f1() << std::endl; // 2 
    std::cout << my_f1() << std::endl; // 3 
    std::cout << my_f1() << std::endl; // 4 

    std::cout << my_f() << std::endl; // 14 
} 

我不應該忘記引入一個未定義的行爲(鐺版本被返回一個垃圾值)可變的關鍵字。 正如實施,關閉工作正常(海灣合作委員會和叮噹聲)

+0

要確定的是,如果你在'my_f1()'之後再次運行my_f()'會很好,因爲它可能仍然是你剛纔直接分配給'make_my_closure '。 – dividebyzero

+1

'x'是'make_my_closure'中的臨時值。 所以海事組織是沒有道理的。我添加了你問的案例。 其行爲如預期 – Setepenre

相關問題