【发布时间】:2021-04-14 13:52:14
【问题描述】:
The example on the page of std::ref/std::cref 显示使用std::ref/std::cref 将参数传递给std::bind,看起来std::bind 通过引用获取参数,而实际上它通过值获取所有参数。
只看那个例子,我也可能不知道std::reference_wrapper 的存在,而std::ref 只是一个允许链接示例表现出的行为的函数。
这就是我在问题标题中以及以下内容中 std::refworks 的意思。
主要是为了好玩,我自己尝试实现std::ref,然后我想出了这个:
template<typename T>
struct ref_wrapper {
ref_wrapper(T& t) : ref(t) {}
T& ref;
operator T&() const {
return ref;
}
};
template<typename T>
ref_wrapper<T> ref(T& t) {
return ref_wrapper{t}; // Ooops
}
template<typename T>
ref_wrapper<const T> cref(const T& t) {
return ref_wrapper{t}; // Ooops
}
在标记为// Ooops 的行中我错误地使用了CTAD,因为我正在使用-std=c++17 进行编译。通过在这两种情况下将ref_wrapper 更改为ref_wrapper<T> 和ref_wrapper<const T> 可以更正此问题。
然后我偷看了/usr/include/c++/10.2.0/bits/refwrap.h。
一方面,我看到我对ref/cref 的实现与std::ref/std::cref 的实现非常相似。
另一方面,我看到std::reference_wrapper 大约有 60 行长!里面有很多东西,包括noexcept、宏、复制ctor、复制operator=、get。
我认为其中大部分与 std::reference_wrapper 的使用无关仅作为 std::ref 的奴隶,但有些东西可能是相关的,例如作为具有通用引用的构造函数。
所以我的问题是:就我的瘦身尝试而言,std::reference_wrapper 的哪些部分是std::ref 工作的必要条件和充分条件?
我刚刚意识到std::reference_wrapper on cppreference 的可能实现(它比来自 GCC 的噪声小)。然而,即使在这里,也有一些我不明白的原因,例如operator()。
【问题讨论】:
-
引用包装器的许多功能应该如何表现在 C++ 标准的其他部分。
std::thread和std::bind之类的东西知道std::referene_wrapper及其工作原理,因此他们可以利用这些知识来处理它。
标签: c++ c++11 ref reference-wrapper