是否可以根据编译时间信息有条件地选择lambda的捕获方法?例如...
auto monad = [](auto && captive) {
return [(?)captive = std::forward<decltype(captive)>(captive)](auto && a) {
return 1;
};
};
Run Code Online (Sandbox Code Playgroud)
我希望通过引用捕获,如果decltype(captive)是a std::reference_wrapper,则通过值捕获所有其他内容.
Lambda 捕获类型无法由模板相关名称控制。
但是,您可以通过将创建内部 lambda 委托给重载函数来实现所需的效果:
template<class T>
auto make_monad(T&& arg) {
return [captive = std::forward<T>(arg)](auto&& a) {
std::cout << __PRETTY_FUNCTION__ << " " << a << '\n';
return 1;
};
}
template<class T>
auto make_monad(std::reference_wrapper<T> arg) {
return [&captive = static_cast<T&>(arg)](auto&& a) {
std::cout << __PRETTY_FUNCTION__ << " " << a << '\n';
return 1;
};
}
int main() {
auto monad = [](auto&& captive) {
return make_monad(std::forward<decltype(captive)>(captive));
};
int n = 1;
monad(1)(1);
monad(n)(2);
monad(std::ref(n))(3);
}
Run Code Online (Sandbox Code Playgroud)
输出:
make_monad(T&&)::<lambda(auto:1&&)> [with auto:1 = int; T = int] 1
make_monad(T&&)::<lambda(auto:1&&)> [with auto:1 = int; T = int&] 2
make_monad(std::reference_wrapper<_Tp>)::<lambda(auto:2&&)> [with auto:2 = int; T = int] 3
Run Code Online (Sandbox Code Playgroud)
我不想通过引用捕获reference_wrapper,我想通过引用捕获它所持有的引用。引用包装器最好是像引用一样,但由于调用运算符(又名“.”运算符)不能重载,因此它最终会失败得很惨。
在这种情况下,您不需要更改 的捕获类型std::reference_wrapper<T>。相反,您可能希望像任何其他类型的参数一样通过值捕获它,并在使用站点首先解开参数:
template<class T> T& unwrap(T& t) { return t; }
template<class T> T& unwrap(std::reference_wrapper<T> t) { return t; }
auto monad = [](auto && captive) {
return [captive](auto && a) { // <--- Capture by value.
auto& captive_ref = unwrap(captive); // <--- Unwrap before usage.
return 1;
};
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
380 次 |
| 最近记录: |