2017-02-09 61 views
1

我已存儲std::function,這是std::bind結果替換調用值,在列表中:性病::功能

typedef std::pair<int, std::function<void(HDC)>> myPair; 

std::list<myPair> *paintJobs; 
paintJobs = new std::list<myPair>(); 

我然後我補充這樣的:

int id = 1; 
int x = 0; 
int y = 0; 
int width = 100; 
int height = 100; 
int r = 255; 
int g = 0; 
int b = 0; 
std::function<void(HDC)> func = std::bind(&Window::drawRect, this, std::placeholders::_1, x, y, width, height, r, g, b); 
paintJobs->push_back(std::make_pair(id, func)); 

在我繪製方法我通過列表並調用所有函數,我已經添加了。這部分運作良好。

但現在,我想換例如色(R,G和B):

void changeColor(int id, int r, int g, int b) { 
    for(auto elem = paintJobs->begin(); elem != paintJobs->end(); ++elem) { 
     if(elem->first == id){ 

      //change the 6th, 7th and 8th parameter of elem->second 
     } 
    } 
} 

我的另一個想法是插入一個新條目,並複製舊的價值觀,但在其他問題:獲取綁定值。

那麼,我該如何替換參數的邊界值或獲取其他參數的值呢?

+2

[OT]:'std :: list * paintJobs;'...不必要的指針,'std :: list paintJobs;'可能是你想要的。 – Jarod42

+0

這是一個更復雜的嵌入類,因此指針 –

+0

如果你想改變「成員」,那麼你應該創建一個仿函數並提供對它們的訪問。然後你可以存儲該函數而不是'std :: function'。 – NathanOliver

回答

1

存儲std::function<void(HDC, int r, int g, int b)>(或同等版本)而不是std::function<void(HDC)>。還存儲一個struct {int r,g,b;}

struct rgb { int r,g,b; }; 
struct rgb_func { 
    rgb color; 
    std::function<void(HDC, rgb)> f; 
    void operator()(HDC hdc)const{ 
    return f(hdc, color); 
    } 
}; 

std::function<void(HDC, rgb)> func = 
    [this, x, y, width, height](HDC hdc, rgb color)->void 
    { 
    this->drawRect(hdc, x, y, width, height, color.r, color.g, color.b); 
    }; 
paintJobs->push_back(std::make_pair(id, rgb_func{ {r,g,b}, func })); 

然後去改變它:

void changeColor(int id, int r, int g, int b) { 
    for(auto elem = paintJobs->begin(); elem != paintJobs->end(); ++elem) { 
    if(elem->first == id){ 
     elem->second.color = {r,g,b}; 
    } 
    } 
} 

注意的second類型不再是std::function<void(HDC)>,但它是可轉換到std::function<void(HDC)>而不是從它。這種轉換可能會導致適度的開銷;在這種情況下使用auto&將避免它。

未經測試的代碼;設計是完善的。有可能tpyos。我會讓rgb更好一些(比如,保證調零或其他)。

我用lambda代替std::bind,因爲std::bind令人困惑,並且在添加到std時已經過時了。

順便

void changeColor(int id, int r, int g, int b) { 
    for(auto& elem:*paintJobs) { 
    if(elem.first == id){ 
     elem.second.color = {r,g,b}; 
    } 
    } 
} 

是少了很多混亂。

+0

它工作後,有點擺弄 –

0

你可以做一個解決方案如下所示:

  1. 存儲在其他位置綁定參數。
  2. 傳遞給你的函數std::bind(f, ..., std::ref(param)...)

的想法是可以修改的參數:

std::function<void(HDC)> func = std::bind(&Window::drawRect, this, std::placeholders::_1, std::ref(x)... 

現在你可以修改來自外部的參數,當函數被再次調用它會使用新的價值。

另一種解決方案是更改您的std::function的簽名,以便爲每個呼叫使用參數。