I have the following C++ code:
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <chrono>
void ThreadFunc(std::vector<int>* pIntVector, std::mutex* pMtx, int i, int j) {
std::lock_guard<std::mutex> lock(*pMtx);
for ( i; i < j; i++)
{
pIntVector->push_back(i);
std::wcout << L"Current thread: " << std::this_thread::get_id() << L"\n";
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
int main() {
const std::vector<int> vec{};
const std::mutex mtx{};
std::thread t1(ThreadFunc, &vec, &mtx, 0, 50);
std::thread t2(ThreadFunc, &vec, &mtx, 100, 150);
t1.join();
t2.join();
return 0;
}
When I try to compile this with MSVC++, the following error is thrown:
C:/data/msvc/14.36.32530-Pre/include\thread(55): error C2672: 'std::invoke': no matching overloaded function found
C:/data/msvc/14.36.32530-Pre/include\type_traits(1580): note: could be 'unknown-type std::invoke(_Callable &&,_Ty1 &&,_Types2 &&...) noexcept(<expr>)'
C:/data/msvc/14.36.32530-Pre/include\thread(55): note: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Ty1 &&,_Types2 &&...) noexcept(<expr>)'
C:/data/msvc/14.36.32530-Pre/include\thread(55): note: With the following template arguments:
C:/data/msvc/14.36.32530-Pre/include\thread(55): note: '_Callable=void (__cdecl *)(std::vector<int,std::allocator<int>> *,std::mutex *,int,int)'
C:/data/msvc/14.36.32530-Pre/include\thread(55): note: '_Ty1=const std::vector<int,std::allocator<int>> *'
C:/data/msvc/14.36.32530-Pre/include\thread(55): note: '_Types2={const std::mutex *, int, int}'
C:/data/msvc/14.36.32530-Pre/include\type_traits(1574): note: or 'unknown-type std::invoke(_Callable &&) noexcept(<expr>)'
C:/data/msvc/14.36.32530-Pre/include\thread(55): note: 'unknown-type std::invoke(_Callable &&) noexcept(<expr>)': expects 1 arguments - 5 provided
C:/data/msvc/14.36.32530-Pre/include\thread(62): note: see reference to function template instantiation 'unsigned int std::thread::_Invoke<_Tuple,0,1,2,3,4>(void *) noexcept' being compiled
with
[
_Tuple=_Tuple
]
C:/data/msvc/14.36.32530-Pre/include\thread(71): note: see reference to function template instantiation 'unsigned int (__cdecl *std::thread::_Get_invoke<_Tuple,0,1,2,3,4>(std::integer_sequence<size_t,0,1,2,3,4>) noexcept)(void *)' being compiled
C:/data/msvc/14.36.32530-Pre/include\thread(88): note: see reference to function template instantiation 'void std::thread::_Start<void(__cdecl &)(std::vector<int,std::allocator<int>> *,std::mutex *,int,int),_Ty,const std::mutex*,int,int>(_Fn,_Ty &&,const std::mutex *&&,int &&,int &&)' being compiled
with
[
_Ty=const std::vector<int,std::allocator<int>> *,
_Fn=void (__cdecl &)(std::vector<int,std::allocator<int>> *,std::mutex *,int,int)
]
<source>(21): note: see reference to function template instantiation 'std::thread::thread<void(__cdecl &)(std::vector<int,std::allocator<int>> *,std::mutex *,int,int),const std::vector<int,std::allocator<int>>*,const std::mutex*,int,int,0>(_Fn,const std::vector<int,std::allocator<int>> *&&,const std::mutex *&&,int &&,int &&)' being compiled
with
[
_Fn=void (__cdecl &)(std::vector<int,std::allocator<int>> *,std::mutex *,int,int)
]
What would be the cause of this error and how can I fix that?
Edit: I made both vec
and mtx
non-const and now the program works as expected. But what I do not understand is, isn't declaring a variable as const
essentially make it a "constant reference" to an object? which make us able to modify its members?
BTW, I'm from a C# background.
There are multiple issues with the provided code:
const
mutex
and vector
and later modifying them can't workvoid ThreadFunc(std::vector<int> &pIntVector, std::mutex &pMtx, int i, int j)
{
// ... change `->` to `.`
}
int main() {
std::vector<int> vec{};
std::mutex mtx{};
std::thread t1(ThreadFunc, std::ref(vec), std::ref(mtx), 0, 50);
std::thread t2(ThreadFunc, std::ref(vec), std::ref(mtx), 100, 150);
//...
}