我正在尝试完美转发,发现
std::forward()需要两个重载:
过载 1:
template <typename T>
inline T&& forward(typename
std::remove_reference<T>::type& t) noexcept
{
return static_cast<T&&>(t);
}
Run Code Online (Sandbox Code Playgroud)
重载nr.2:
template <typename T>
inline T&& forward(typename
std::remove_reference<T>::type&& t) noexcept
{
static_assert(!std::is_lvalue_reference<T>::value,
"Can not forward an rvalue as an lvalue.");
return static_cast<T&&>(t);
}
Run Code Online (Sandbox Code Playgroud)
现在,完美转发的典型场景是
template <typename T>
void wrapper(T&& e)
{
wrapped(forward<T>(e));
}
Run Code Online (Sandbox Code Playgroud)
当然,您知道何时wrapper()实例化T取决于传递给它的参数是左值还是右值。如果它是type的左值U,T则推导为U&。如果是右值,T则推导为U。
无论如何-在-的范围内wrapper()- e是一个左值,因此它始终使用的第一个重载std::forward()。
现在我的问题是:
使用(需要)第二重载的有效方案是什么?
在书里
Anthony Williams的“ C ++并发性”
您可以找到以下两个代码段(我进行了一些细微的修改):
片段1:
class thread_guard
{
std::thread& t;
public:
explicit thread_guard(std::thread& t_): t(t_){}
~thread_guard()
{
if(t.joinable())
{
t.join();
}
}
thread_guard(thread_guard const&)=delete;
thread_guard& operator=(thread_guard const&)=delete;
};
void my_func()
{
for(int j = 0; j < 1000; ++j)
{
cout << "\n " << j;
}
}
void f()
{
std::thread t1(my_func);
thread_guard g(t1);
do_something_in_current_thread();
}
int main()
{
f();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
继续你可以找到
片段2:
class scoped_thread
{
std::thread t;
public:
explicit scoped_thread(std::thread t_): t(std::move(t_))
{
if(!t.joinable()) …Run Code Online (Sandbox Code Playgroud)