如果线程函数 delaration 更改为void thr(std::shared_ptr<Base>& p).Complie 错误,为什么编译器会抱怨:
gcc-10.1.0/include/c++/10.1.0/thread: 在 '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: 错误: 静态断言失败: std::thread 参数在转换为右值后必须是可调用的
136 | 类型名称衰减<_Args>::type...>::value,
谁能给我解释一下,一步一步。
对于这个问题的任何提示,我将不胜感激。
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
struct Base
{
Base() { std::cout << " Base::Base()\n"; }
// Note: non-virtual destructor is OK here
~Base() { std::cout << " Base::~Base()\n"; }
};
struct Derived: public Base
{
Derived() { std::cout << " Derived::Derived()\n"; }
~Derived() { std::cout << " Derived::~Derived()\n"; }
};
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:\n"
<< " lp.get() = " << lp.get()
<< ", lp.use_count() = " << lp.use_count() << '\n';
}
}
int main()
{
std::shared_ptr<Base> p = std::make_shared<Derived>();
std::cout << "Created a shared Derived (as a pointer to Base)\n"
<< " p.get() = " << p.get()
<< ", p.use_count() = " << p.use_count() << '\n';
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\n"
<< "ownership from main:\n"
<< " p.get() = " << p.get()
<< ", p.use_count() = " << p.use_count() << '\n';
t1.join(); t2.join(); t3.join();
std::cout << "after joining the threads\n" <<
" p.get() = " << p.get() << ", p.use_count() " <<p.use_count() << std::endl;
std::cout << "All threads completed, the last one deleted Derived\n";
}
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
Jon*_*ely 11
传递给std::thread构造函数的参数将被复制,然后作为右值转发给在新线程中运行的函数。所以当你创建一个std::thread这样的:
std::thread t1(thr, p)
Run Code Online (Sandbox Code Playgroud)
参数p将被复制,然后作为右值转发。如果函数thr需要左值引用,则不能用右值调用它。
静态断言告诉您不能thr(shared_ptr<Base>&)使用 rvalue 进行调用shared_ptr<Base>。(在我添加静态断言之前,你刚刚从 的内部深处得到了一个可怕的模板实例化错误std::thread,现在的想法是它告诉你英语有什么问题)。
The solution to passing a reference into the function is to use the std::ref function to create a reference_wrapper object:
std::thread t1(thr, std::ref(p))
Run Code Online (Sandbox Code Playgroud)
This will create a std::reference_wrapper<std::shared_ptr<Base>> which gets copied and forwarded to thr as an rvalue, and then that rvalue can be converted to shared_ptr<Base>& to initialize the parameter of the thr function.
This is also clearly explained at https://en.cppreference.com/w/cpp/thread/thread/thread#Notes
| 归档时间: |
|
| 查看次数: |
5669 次 |
| 最近记录: |