6

I'm trying to run a function called dcp in a thread, I've to run this function three times independently. So here's how I'm implemented that:

void dcp(cv::Mat&, int, int, cv::Mat&, double);

int main(int argc, char* argv[])
{
cv::Mat IllumTrans;
//fill IllumTrans

std::vector<cv::Mat> rgbDCP;
rgbDCP.reserve(3);
//Fill it

std::thread thread_1(dcp, rgb[0], rows, cols, IllumTrans, A[0]);
std::thread thread_2(dcp, rgb[1], rows, cols, IllumTrans, A[1]);
std::thread thread_3(dcp, rgb[2], rows, cols, IllumTrans, A[2]);

thread_1.join();
thread_2.join();
thread_3.join();
}

But I get that error of no matching function for call:

In file included from 21022018WorksfineOneimageThread.cpp:6:0:
/usr/include/c++/7/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >’:
/usr/include/c++/7/thread:127:22:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(cv::Mat&, int, int, cv::Mat&, double); _Args = {cv::Mat&, int&, int&, cv::Mat&, int&}]’
21022018WorksfineOneimageThread.cpp:136:65:   required from here
/usr/include/c++/7/thread:240:2: error: no matching function for call to ‘std::thread::_Invoker<std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >::_M_invoke(std::thread::_Invoker<std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >::_Indices)’
  operator()()
  ^~~~~~~~
/usr/include/c++/7/thread:231:4: note: candidate: template<long unsigned int ..._Ind> decltype (std::__invoke((_S_declval<_Ind>)()...)) std::thread::_Invoker<_Tuple>::_M_invoke(std::_Index_tuple<_Ind ...>) [with long unsigned int ..._Ind = {_Ind ...}; _Tuple = std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int>]
    _M_invoke(_Index_tuple<_Ind...>)
    ^~~~~~~~~
/usr/include/c++/7/thread:231:4: note:   template argument deduction/substitution failed:
/usr/include/c++/7/thread: In substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1, 2, 3, 4, 5}]’:
/usr/include/c++/7/thread:240:2:   required from ‘struct std::thread::_Invoker<std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >’
/usr/include/c++/7/thread:127:22:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(cv::Mat&, int, int, cv::Mat&, double); _Args = {cv::Mat&, int&, int&, cv::Mat&, int&}]’
21022018WorksfineOneimageThread.cpp:136:65:   required from here
/usr/include/c++/7/thread:233:29: error: no matching function for call to ‘__invoke(std::__tuple_element_t<0, std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >, std::__tuple_element_t<1, std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >, std::__tuple_element_t<2, std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >, std::__tuple_element_t<3, std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >, std::__tuple_element_t<4, std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >, std::__tuple_element_t<5, std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >)’
    -> decltype(std::__invoke(_S_declval<_Ind>()...))
                ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/tuple:41:0,
                 from /usr/include/c++/7/functional:54,
                 from /usr/local/include/opencv2/core/utility.hpp:60,
                 from /usr/local/include/opencv2/core.hpp:3261,
                 from 21022018WorksfineOneimageThread.cpp:1:
/usr/include/c++/7/bits/invoke.h:89:5: note: candidate: template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...)
     __invoke(_Callable&& __fn, _Args&&... __args)
     ^~~~~~~~
/usr/include/c++/7/bits/invoke.h:89:5: note:   template argument deduction/substitution failed:
/usr/include/c++/7/bits/invoke.h: In substitution of ‘template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = void (*)(cv::Mat&, int, int, cv::Mat&, double); _Args = {cv::Mat, int, int, cv::Mat, int}]’:
/usr/include/c++/7/thread:233:29:   required by substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1, 2, 3, 4, 5}]’
/usr/include/c++/7/thread:240:2:   required from ‘struct std::thread::_Invoker<std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >’
/usr/include/c++/7/thread:127:22:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(cv::Mat&, int, int, cv::Mat&, double); _Args = {cv::Mat&, int&, int&, cv::Mat&, int&}]’
21022018WorksfineOneimageThread.cpp:136:65:   required from here
/usr/include/c++/7/bits/invoke.h:89:5: error: no type named ‘type’ in ‘struct std::__invoke_result<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int>’

I'm compiling my program like that:

g++ -std=c++1z -fomit-frame-pointer -O3 -ffast-math -mmmx -msse -msse2 -msse3 -DNDEBUG -Wall 21022018WorksfineOneimageThread.cpp -o 21022018WorksfineOneimageThread -fopenmp `pkg-config --cflags --libs opencv`

gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3~16.04.1) 
6
  • 2
    Possible duplicate of std::thread pass by reference calls copy constructor Commented May 13, 2018 at 14:58
  • You are missing a bunch of headers, including the one std::thread is defined in. Commented May 13, 2018 at 14:58
  • @hlt I couldn't guess that I need to pass y reference! Commented May 13, 2018 at 15:09
  • @juanchopanza I didn't include any includes in my post and this is not the issue Commented May 13, 2018 at 15:09
  • @Ja_cpp You should post a minimal reproducible example. Commented May 13, 2018 at 15:47

2 Answers 2

20

Your function expects a reference (cv::Mat&) as its first and fourth arguments, but you're passing just cv::Mat, so you should wrap these in std::ref:

std::thread thread_1(dcp, std::ref(rgb[0]), rows, cols, std::ref(IllumTrans), A[0]);
Sign up to request clarification or add additional context in comments.

2 Comments

That solve my issue. I want to know how could I know that the function expects a reference from the error I got?
@Ja_cpp, the second line says: /usr/include/c++/7/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (*)(cv::Mat&, int, int, cv::Mat&, double), cv::Mat, int, int, cv::Mat, int> >’:. So, the first template argument to std::thread::_Invoker holds the types of the function's arguments.
1

I'd like to point out something in case someone runs into the same problem as me.

I had a similar problem where I was launching a thread from within a const member function. The function that the thread was going to execute wasn't const because it needed to modify the member variables of the object that created it, but since the this pointer was const due to being called from a const function the compiler complained with an error similar to OP's.

I can't share my code but I'll share something similar to demonstrate the issue.

void FooClass::setup() const  // The const here was my problem
{
  // Here, the 'this' pointer is const due to the setup function being const
  // but the thread_routine function expects it no to be const.
  std::thread(&FooClass::thread_routine, this).detach();
}

void FooClass::thread_routine()
{
  // Do something with member variables
}

Hope this helps anyone in the future.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.