2016-02-26 2 views
0

Как бы найти элемент в векторе из одного из его аргументов, заданных с помощью emplace_back Попытка отсоединить поток, а затем удалить его из вектора.Найти элемент в векторе из одного из его аргументов

std::vector<std::thread> vTimerThreads; 
void SetTimer(UINT ID, DWORD dwMilliseconds) 
{ 
    // timerThreadProc is my thread that handles my timers 
    vTimerThreads.emplace_back(timerThreadProc, ID, dwMilliseconds); 
} 
void DeleteTimer(UINT ID) 
{ 
    //Find thread by ID? 
    // thread.detach(); 
    // then delete 
} 

SetTimer(TIMER1, 5000); 
+1

Вы не сохранили 'ID' в любом месте, по крайней мере, в любом месте, доступном из вектора. – chris

ответ

1

Если вы хотите, чтобы сделать простой линейный поиск (что имеет смысл, если число потоков не велико), вы можете просто сделать

void DeleteTimer(UINT ID) 
{ 
    for(int i = 0; i < vTimerThreads.size(); i++) 
    if(vTimerThreads[i].get_id() == ID) 
    { 
     vTimerThreads.erase(vTimerThreads.begin()+i); 
     break; 
    } 
} 

Если количество потоков велико, произвольное удаление как это дорого - вы можете рассмотреть что-то вроде forward_list вместо vector в этом случае.

+0

Вы только что внедрили 'std :: find_if'. – chris

+0

Да, я не знал об этой функции. Спасибо за совет. Я отредактирую ответ. –

+0

ID не std :: thread :: get_id() – ramafe

3

std::find_if звучит так, как будто вы хотите, если вы собираетесь удалить на основе id.

void DeleteTimer(std::thread::id ID) 
{ 
    std::vector<std::thread>::iterator itr = std::find_if(vTimerThreads.begin(), vTimerThreads.end(), [&](const std::thread& t) { return t.get_id() == ID; }); 
    if(itr != vTimerThreads.end()) 
     vTimerThreads.erase(itr); 
} 

Здесь я использовал лямбда, но это необязательно.

Если вы думаете об использовании большого количества потоков, возможно, другая структура данных подойдет вам лучше. Вы считали std :: set для более быстрого поиска? Возможно, даже карта или hash_map были бы полезны для вас, где id является ключом? Вы можете помещать потоки в эти контейнеры с семантикой перемещения вместо emplace_back без копирования (поскольку, как я подозреваю, мотивирует вас использовать emplace).

Отъезд std::algorithm library хотя, есть некоторые большие вещи там

EDIT: я вижу в одном из комментариев OP говорит, что ID не на самом деле идентификатор потока. Если мы не сможем выяснить, какой член T для std::vector<T> предназначен для поиска, явное решение не может быть предоставлено.

Пока я делаю редактирование, вот какой код для добавления потоков в std :: map без копирования. В следующем коде будет тривиально найти элемент по std :: thread :: id или тому, что вы хотите использовать в качестве ключа, а затем удалить его.

std::map<std::thread::id, std::thread> mapTimerThreads; 

void AddNewThreadToMap() 
{ 
    std::thread t; 
    mapTimerThreads[t.get_id()] = std::move(t); 
} 
+1

Перед стиранием вы должны проверить 'itr! = VTimerThreads.end()'. – Jarod42

+0

@ Jarod42 О, черт возьми, я не могу поверить, что оставил это. Спасибо, что поймали это! Я отредактировал ответ с этим дополнением. –

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