2016-05-02 7 views
0

Я пытаюсь поместить условие внутри функции, но оно бросает запутанную ошибку времени компиляции. Хотя, если я пишу его в лямбда-функции, подобной этой [] {retur i == k;}, она показывает, что k не идентифицировано. Кто-нибудь может сказать, как решить эту проблему.Проблема в предикатной функции в ожидании в потоке C++

#include <iostream> 
#include <mutex> 
#include <sstream> 
#include <thread> 
#include <chrono> 
#include <condition_variable> 
using namespace std; 
condition_variable cv; 
mutex m; 
int i; 
bool check_func(int i,int k) 
{ 
    return i == k; 
} 
void print(int k) 
{ 
    unique_lock<mutex> lk(m); 
    cv.wait(lk,check_func(i,k));   // Line 33 
    cout<<"Thread no. "<<this_thread::get_id()<<" parameter "<<k<<"\n"; 
    i++; 
    return; 
} 
int main() 
{ 
    thread threads[10]; 
    for(int i = 0; i < 10; i++) 
     threads[i] = thread(print,i); 
    for(auto &t : threads) 
     t.join(); 
    return 0; 
} 

Ошибка компилятор:

In file included from 6:0: 
/usr/include/c++/4.9/condition_variable: In instantiation of 'void std::condition_variable::wait(std::unique_lock<std::mutex>&, _Predicate) [with _Predicate = bool]': 
33:30: required from here 
/usr/include/c++/4.9/condition_variable:97:14: error: '__p' cannot be used as a function 
    while (!__p()) 
      ^

ответ

2

wait() принимает предикат, который является вызываемой одноместный функции возвращения BOOL. wait() использует этот предикат, как так:

while (!pred()) { 
    wait(lock); 
} 

check_func(i,k) является bool. Это не подлежит вызову, и это постоянный - который побеждает цель. Вы ждете от чего-то, что может измениться. Вы должны обернуть его в чем-то, что может быть повторно вызываемым - как лямбда:

cv.wait(lk, [&]{ return check_func(i,k); }); 
+0

Чтобы прояснить немного, это не является константой - это выражение, которое вычисляется логическое значение, и это значение является то, что передается 'wait' (а не сама функция). – Cameron

+0

Я считаю, что перед check_func должно быть ключевое слово return. После этого он не вызывает ошибки времени компиляции. Но после этого его повесили, и ограничение времени превысило и вышло без печати ничего? – user3798283

+0

@user Ну, все ваши потоки ждут чего-то, что никогда не произойдет. Это ошибка логики программирования. – Barry