2017-02-09 10 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;' ...uneeded pointer, 'std :: list paintJobs;' возможно, что вы хотите. – Jarod42

+0

Это немного сложнее в встроенном классе, поэтому указатель –

+0

Если вы хотите изменить «участников», тогда вы должны создать функтор и предоставить им доступ. Затем вы можете сохранить этот функтор вместо 'std :: function'. – NathanOliver

ответ

1

Хранить a 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 немного лучше (например, гарантировать обнуление или что-то еще).

Я использовал лямбда вместо 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. Pass вашей функции std::bind(f, ..., std::ref(param)...)

Идея заключается в том, чтобы иметь возможность изменять параметры:

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

Теперь вы можете изменять параметры снаружи, когда функция вызывается снова будет использовать новые значения.

Другим решением было бы изменить подпись вашего std::function, чтобы принимать параметры для каждого вызова.

 Смежные вопросы

  • Нет связанных вопросов^_^