c++ - const 限定符和前向引用
问题描述
在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&>
导致这两个 ctors
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
with work
object的实例化引发编译时错误
<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
是冲突的,而且添加&&
toFunc
并不会使其成为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
到折叠的引用没有任何效果?
还是我的观察是错误的?
解决方案
对于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)) {}
推荐阅读
- python - 替换numpy数组中的元素
- python - 如何检查条目中的值是否在列表中?
- haxe - 如何使用表达式宏返回类实例?
- vue.js - 如何更改元素 UI 表中特定行的样式
- xquery - 无法编译 xquery : err:XPST0003 地图表达式中不再接受 ':=' 表示法
- android-room - 如何改造和房间处理嵌套对象
- powershell - 用于搜索文件夹的 Powershell 脚本删除它们创建包含特定数据的日志文件
- java - Http Ok3 返回两个响应
- c# - 不知何故,我的值永远不会等于 1,这是有原因的吗?
- javascript - 无法在我的应用程序中找到下拉输入字段的元素