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的签名,以便为每个呼叫使用参数。