常量限定符和前向引用
Const qualifier and forward reference
在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
实例化为导致这两个 ctor 的lambda_task<Func&>
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
不起作用?
还是我的观察是错误的?
表示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)) {}
相关文章:
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 为什么我可以通过引用修改常量返回
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 将常量指针引用绑定到非常量指针
- 通过常量引用传递参数的矩阵模板类
- 按值捕获引用时出现非常量
- 在C++中使用非常量引用作为常量
- 具有常量引用参数的函数模板专用化
- 多个"常量引用"变量可以共享同一个内存吗?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 为什么按值传递QStringView比引用常量更快?
- 通过引用常量函数调用另一个类的非常量函数
- 构造常量对象与引用常量对象
- 引用“常量value_type”时出错
- 为什么可以在 for 语句中重新分配引用常量
- 程序反馈:命名循环索引和引用常量数据
- 堆还是栈?在c++中函数调用中引用常量字符串时
- 为什么常量结构数组在按名称引用常量结构时不放在 .rodata 中?
- 为什么编译器允许在函数中发送对迭代器的引用,该函数引用常量迭代器