已经在seastar框架中看到了这段代码
template <typename Func>
class lambda_task final : public task {
Func _func;
public:
lambda_task(scheduling_group sg, const Func& func) : task(sg),
_func(func) {}
lambda_task(scheduling_group sg, Func&& func) : task(sg),
_func(std::move(func)) {}
virtual void run_and_dispose() noexcept override {
_func();
delete this;
}
};
template <typename Func>
inline std::unique_ptr<task> make_task(Func&& func) {
return std::make_unique<lambda_task<Func>>(current_scheduling_group(),
std::forward<Func>(func));
}
using scheduling_group = int;
auto current_scheduling_group(){ return int{};}
//为简单起见
让我们假设我要像下面那样实例化task
auto work = [](){...}
make_task(work);
因此,由于work
是lvalue
make_task(Func&&)
-> make_task(Func&)
,并且将lambda_task
实例化为lambda_task<Func&>
,这导致了这两个ctor < / p>
lambda_task(scheduling_group sg, const Func& func)
lambda_task(scheduling_group sg, Func&& func)
成为(我想会成为)
lambda_task(scheduling_group sg, **const Func& func**)
lambda_task(scheduling_group sg, **Func& func**)
用lambda_task
对象实例化work
会引发编译时错误
<source>:127:5: error: 'lambda_task<Func>::lambda_task(scheduling_group, Func&&) [with Func = main()::<lambda()>&; scheduling_group = int]'
cannot be overloaded with 'lambda_task<Func>::lambda_task(scheduling_group, const Func&) [with Func = main()::<lambda()>&; scheduling_group = int]'
lambda_task(scheduling_group sg, Func&& func) : task(sg), _func(std::move(func)) {}
^~~~~~~~~~~
<source>:126:5: note: previous declaration 'lambda_task<Func>::lambda_task(scheduling_group, const Func&)
[with Func = main()::<lambda()>&; scheduling_group = int]'
为了使它起作用,我所做的就是改变
lambda_task(scheduling_group sg, Func&& func) to
lambda_task(scheduling_group sg, std::remove_reference_t<Func>&& func)
问题1:我是对还是错?我的零钱会破坏任何东西吗?还是需要?
我意识到
lambda_task(scheduling_group sg, const Func& func)#1
lambda_task(scheduling_group sg, Func && func)#2
#1 & #2
发生冲突,并且在&&
上添加Func
并不能使其成为rvalue
,因为它被引用折叠为lvalue
(所以我使用过的std :: remove_reference_t)
问题2:
假设T&&
是前向引用[T = int],并折叠为T&
。
为什么std::is_same<const int&, const T&>
不正确?
<source>:162:5: required from 'void maketest(T&&) [with T = int&]'
<source>:154:18: error: static assertion failed
static_assert(std::is_same<const int&,const T&>::value,"");
为什么将const
添加到折叠的引用中没有任何效果?
还是我的观察是错误的?
答案 0 :(得分:8)
对于template <typename T> class lambda_task
,用lambda_task<F&>
,
我们有
const T&
= T const&
= F&
T&&
= F&
。您可能希望同时衰减T
和const F&
和F&&
:
lambda_task(scheduling_group sg, const std::decay_t<Func>& func) : task(sg), _func(func) {}
lambda_task(scheduling_group sg, std::decay_t<Func>&& func) : task(sg), _func(std::move(func)) {}