2011-12-20 44 views
1

在我的項目中,有兩個組件:生產者和消費者。生產者負責處理一些信息並將結果提供給消費者。結果通過函數對象傳遞。使用std :: function時額外拷貝構造函數

我正在使用傳遞此信息的函數。你可以看到它在下面的代碼中的外觀。

#include <iostream> 
#include <vector> 
#include <functional> 

using namespace std; 

class Data { 
    std::vector<int> vec; 
public: 
    Data() { 
     cout << "Data()" << endl; 
    } 

    Data(const Data& rr) : vec(rr.vec) { 
     cout << "Data(Data&)" << endl; 
    } 

    ~Data() { 
     cout << "~Data()" << endl; 
    } 

    Data(Data&& rr) : vec(move(rr.vec)) { 
     cout << "Data(Data&&)" << endl; 
    } 

    void get() { 
    } 
}; 

class Producer { 
public: 
    void process(function<void(Data)> f) { 
     Data data; 
     f(move(data)); 
    } 

    void process2(void(&pf)(Data)) { 
     Data c; 
     pf(move(c)); 
    } 

}; 

void Consume(Data a) { 
    cout << "Consume(data)" << endl; 
} 

int main() { 
    { 
     cout << "use function() " << endl; 
     Producer p; 
     p.process([](Data a) { 
      cout << "Consume(data)" << endl; 
     }); 
    } 

    { 
     cout << endl; 
     cout << "use function pointer" << endl; 
     Producer p;; 
     p.process2(Consume); 
    } 
    return 0; 
} 

它具有以下輸出

use function() 
    Data() 
    Data(Data&&) 
    Data(Data&) 
    Data(Data&) 
    Consume(data) 
    ~Data() 
    ~Data() 
    ~Data() 
    ~Data() 

    use function pointer 
    Data() 
    Data(Data&&) 
    Consume(data) 
    ~Data() 
    ~Data() 

當使用函數對象有另外的拷貝構造函數。

我做錯了什麼?是否有可能擺脫這些額外的構造函數?

預先感謝您。

我正在使用VC10 SP1。

+0

使用g ++它只是調用移動構造函數3次。 – kennytm

+0

'std :: function'很大且很貴......希望你有很好的編譯器優化,但是考慮到'std :: function'提供給你的巨大靈活性,可以優化多少。在緊縮時,當性能問題時,優先使用函數指針或'auto'/lambda通過顯式轉換爲'std :: function'。 –

+5

它將在MSVC11中修復。在這裏看到我的答案:http://stackoverflow.com/questions/8203211/how-can-i-make-the-storage-of-c-lambda-objects-more-efficient/8205037#8205037 –

回答

0

您在這裏有幾個選項。

  • 不要使用std::function,你非捕獲拉姆達可轉換爲void(*)(Data)
  • 不要使用std::function,使你的函數模板,編譯器可以推斷出隱藏式的拉姆達的。
  • 不要複製對象,將它們作爲指針或引用傳遞。根據程序完整版的作用,在堆上分配並使用std::unique_ptr可能更有效。