2014-04-24 1 views
2

Я работаю над многопоточной медианной функцией как частью более крупного проекта. У меня мало опыта на C++. Медианная функция ниже должна взять вектор трехмерных int-векторов и вернуть 3-мерный вектор ints, где каждая запись является медианным значением всех записей в этом индексе во входных векторах. Так что если входной сигнал < < 3,2,1>, < 1,2,3>, < 2,2,2 >>, возврат в < 2,2,2>. Этот код будет использоваться при реализации медианного размытия для использования в режиме реального времени, следовательно, желание многопоточности.C++ 11 Темы: Ошибка передачи вектора функции потока

#include <thread> 
#include <iostream> 
#include <mutex> 
#include <vector> 
#include <algorithm> 
#include "median.h" 

// mutex to protect bgrPixel (possibly not needed) 
std::mutex mtx; 


std::vector<int> median(const std::vector<std::vector<int> >& input) 
{ 
    std::vector<int> bgrPixel;    // Vector to store median BGR value 
    std::thread first(thread_function, bgrPixel, input, 0); // thread for each colour channel 
    std::thread second(thread_function, bgrPixel, input, 1); 
    std::thread third(thread_function, bgrPixel, input, 2); 
    first.join(); 
    second.join(); 
    third.join(); 
    return bgrPixel; 
} 

void thread_function(std::vector<int>& bgrPixel, const std::vector<std::vector<int> >&     input1, int channel) 
{ 

    std::vector<int> input = input1[channel]; // copy the colour channel 
    std::sort(input.begin(), input.end()); 
    int size = input.size(); 
    if (size %2 == 0) // get the median 
    { 
     mtx.lock(); 
     bgrPixel[channel] = (input[size/2] + input[size/2 + 1])/2; 
     mtx.unlock(); 
    } else 
    { 
     mtx.lock(); 
     bgrPixel[channel] = input[(size-1)/2]; 
     mtx.unlock(); 
    } 
} 

Проблемы я имею, во время компиляции, г ++ (и лязг также) дает довольно невнятное сообщение об ошибке:

g++ -std=c++11 -pthread -o median median.cpp 

In file included from /usr/include/c++/4.8.2/thread:39:0, 
        from median.cpp:1: 
/usr/include/c++/4.8.2/functional: In instantiation of ‘struct std::_Bind_simple<void   (*(std::vector<int>, std::vector<std::vector<int> >, int))(std::vector<int>&, const  std::vector<std::vector<int> >&, int)>’: 
/usr/include/c++/4.8.2/thread:137:47: required from ‘std::thread::thread(_Callable&&,   _Args&& ...) [with _Callable = void (&)(std::vector<int>&, const  std::vector<std::vector<int> >&, int); _Args = {std::vector<int, std::allocator<int> >&,  const std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int,  std::allocator<int> > > >&, int}]’ 
median.cpp:15:58: required from here 
/usr/include/c++/4.8.2/functional:1697:61: error: no type named ‘type’ in ‘class    std::result_of<void (*(std::vector<int>, std::vector<std::vector<int> >, int))  (std::vector<int>&, const std::vector<std::vector<int> >&, int)>’ 
     typedef typename result_of<_Callable(_Args...)>::type result_type; 
                 ^
/usr/include/c++/4.8.2/functional:1727:9: error: no type named ‘type’ in ‘class  std::result_of<void (*(std::vector<int>, std::vector<std::vector<int> >, int))  (std::vector<int>&, const std::vector<std::vector<int> >&, int)>’ 
      _M_invoke(_Index_tuple<_Indices...>) 
     ^

я нашел похожее сообщение об ошибке c++11 Thread class how to use a class member function, но это не делает конкретно касайтесь моей проблемы. Любая помощь будет очень признательна, я полностью ожидаю, что это связано с тем, что я не знаю, что я делаю: P

EDIT: Прототипы для thread_function и медианы включены из файла заголовка median.h.

+1

Когда вы получите это скомпилировать у вас есть более окольные проблемы: Ваш 'bgrPixel' вектор не содержит три элемента , поэтому, когда вы выполняете 'bgrPixel [channel] = ...' у вас есть [* неопределенное поведение *] (http://en.wikipedia.org/wiki/Undefined_behavior). Это легко решить, сказав, что вектор имеет три позиции в объявлении: 'std :: vector bgrPixel (3);' –

+3

Поскольку ваши векторы имеют размер 3, вы можете заменить 'std :: vector ' на 'std :: массив '. Это было бы менее подвержено ошибкам. У меня нет компилятора g ++, но он хорошо работает с VC++. Возможно, что-то не так с вашим компилятором. –

+0

Спасибо за это! – chaffdog

ответ

6

Заменить

std::thread first(thread_function, bgrPixel, input, 0); 

по

std::thread first(thread_function, std::ref(bgrPixel), std::ref(input), 0); 

Живой пример: http://coliru.stacked-crooked.com/a/630775aafc3d4642

+0

Спасибо! Это работает отлично! Я также обнаружил, что он будет компилироваться, если я вообще не использую ссылки. Мне нужно прочитать справки. – chaffdog