Why the compiler complains if the the thread function delaration is changed to void thr(std::shared_ptr<Base>& p)
.Complie error:
gcc-10.1.0/include/c++/10.1.0/thread: In instantiation of
'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void
(&)(std::shared_ptr&); _Args = {std::shared_ptr&};
= void]':
gcc-10.1.0/include/c++/10.1.0/thread:136:44: error: static assertion
failed: std::thread arguments must be invocable after conversion to
rvalues
136 | typename decay<_Args>::type...>::value,
Can someone explain me, step by step.
I would be grateful for any hint on this question.
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
struct Base
{
Base() { std::cout << " Base::Base()
"; }
// Note: non-virtual destructor is OK here
~Base() { std::cout << " Base::~Base()
"; }
};
struct Derived: public Base
{
Derived() { std::cout << " Derived::Derived()
"; }
~Derived() { std::cout << " Derived::~Derived()
"; }
};
void thr(std::shared_ptr<Base> p)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::shared_ptr<Base> lp = p; // thread-safe, even though the
// shared use_count is incremented
{
static std::mutex io_mutex;
std::lock_guard<std::mutex> lk(io_mutex);
std::cout << "local pointer in a thread:
"
<< " lp.get() = " << lp.get()
<< ", lp.use_count() = " << lp.use_count() << '
';
}
}
int main()
{
std::shared_ptr<Base> p = std::make_shared<Derived>();
std::cout << "Created a shared Derived (as a pointer to Base)
"
<< " p.get() = " << p.get()
<< ", p.use_count() = " << p.use_count() << '
';
std::thread t1(thr, p), t2(thr, p), t3(thr, p);
p.reset(); // release ownership from main
std::cout << "Shared ownership between 3 threads and released
"
<< "ownership from main:
"
<< " p.get() = " << p.get()
<< ", p.use_count() = " << p.use_count() << '
';
t1.join(); t2.join(); t3.join();
std::cout << "after joining the threads
" <<
" p.get() = " << p.get() << ", p.use_count() " <<p.use_count() << std::endl;
std::cout << "All threads completed, the last one deleted Derived
";
}
The outputs:
Base::Base()
Derived::Derived()
Created a shared Derived (as a pointer to Base)
p.get() = 0x57be80, p.use_count() = 1
Shared ownership between 3 threads and released
ownership from main:
p.get() = 0, p.use_count() = 0
local pointer in a thread:
lp.get() = 0x57be80, lp.use_count() = 4
local pointer in a thread:
lp.get() = 0x57be80, lp.use_count() = 3
local pointer in a thread:
lp.get() = 0x57be80, lp.use_count() = 2
Derived::~Derived()
Base::~Base()
after joining the threads
p.get() = 0, p.use_count() 0
All threads completed, the last one deleted Derived
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…