c ++ передача std :: function с пользовательским объектом в качестве аргумента в потоке - PullRequest
1 голос
/ 31 марта 2019

У меня есть отдельный класс для обработки потоков, и есть функция, необходимая для создания потока и повторения функции для определенного интервала

void timer_start_custom(std::function<void(string, string&, vector<CustomObject>&)> func, string filename, string& lastline, vector<CustomObject>& dict, unsigned int interval){
     std::thread([func, interval, filename, lastline, dict](){
         while (true){
             auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval);
             func(filename, lastline, dict);
             std::this_thread::sleep_until(x);
         }
     }).detach();
}

однако, прямо сейчас компилятор compain:

No matching function for call to object of type 'const
std::function<void (string, string &, vector<RowData> &)>' (aka
'const function<void (basic_string<char, char_traits<char>, allocator<char> >,
basic_string<char, char_traits<char>, allocator<char> > &, vector<RowData> &)>')

Я знаю, если поместить функцию в тот же файл, то я могу пропустить функцию как параметр, но мне все еще очень любопытно и упрямо знать, как это сделать, так как я буду вызывать timer_start_custom в другом файл и передать в разные функции

Ответы [ 2 ]

2 голосов
/ 01 апреля 2019

Захват переменных по значению делает их неявно const в теле лямбды, поэтому передача их в func, так как ссылки на не стоимость не компилируются.

Таким образом, вы можете сделать то, что r3mus n0x рекомендует в их ответе , или передать их в func по значению или как const ref. Я думаю, что я предпочитаю решение r3mus n0x, так как оно включает меньше временных переменных, при условии, что упомянутые переменные не выходят из области видимости во время выполнения потока ..

2 голосов
/ 31 марта 2019

Ваша проблема в том, что вы захватываете lastline и dict по значению и затем передаете их в func, которые ожидают неконстантные ссылки. Вам, вероятно, нужно сделать снимок так:

std::thread([func, interval, filename, &lastline, &dict] {
...
});

Однако вы должны быть особенно осторожны при захвате по ссылке, чтобы убедиться, что эти объекты все еще живы, когда они используются в лямбда-выражениях, особенно если учесть, что вы вызываете его в отдельном потоке. Это также создает возможность гонки данных, поэтому, если вы собираетесь обращаться к lastline и dict из нескольких потоков, вам необходимо убедиться, что используются надлежащие механизмы синхронизации, такие как std::mutex.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...