从 lambda 中的调用函数返回
Return from calling function inside lambda
Lambdas是一种很棒的方法,可以在函数/方法中创建可重用的代码,而不会污染父类。大多数时候,它们是 C 样式宏的非常实用的替代品。
但是,宏中有一点语法糖我似乎无法用 lambda 复制,那就是从包含函数退出的能力。例如,如果我需要在检查一系列int
的范围时返回,我可以使用宏轻松完成:
const int xmin(1), xmax(5);
#define CHECK_RANGE(x) { if((x) < xmin || (x) > xmax) return false; }
bool myFunc(int myint) {
CHECK_RANGE(myint);
int anotherint = myint + 2;
CHECK_RANGE(anotherint);
return true;
}
显然这是一个过于简化的示例,但基本前提是我对不同的变量一遍又一遍地执行相同的检查,我认为封装检查和相关出口更具可读性。不过,我知道宏不是很安全,尤其是当它们变得非常复杂时。但是,据我所知,尝试执行等效的 lambda 需要像这样笨拙的额外检查:
const int xmin(1), xmax(5);
auto check_range = [&](int x) -> bool { return !(x < xmin || x > xmax); };
bool myFunc(int myint) {
if(!check_range(myint)) return false;
int anotherint = myint + 2;
if(!check_range(anotherint)) return false;
return true;
}
有没有办法用 lambda 做到这一点?还是我错过了一些替代解决方案?
编辑:我认识到,除非采取重大预防措施,否则从宏内部返回通常是一个坏主意。我只是想知道这是否可能。
你是对的 - 没有办法从 lambda 内部从调用方返回。由于可以从任意调用方内部捕获和存储 lambda 以供稍后调用,因此这样做会导致不可预测的行为。
class Foo
{
Foo(std::function<void(int)> const& callMeLater) : func(callMeLater) {}
void CallIt(int* arr, int count)
{
for (index = count; index--;)
func(count);
// do other stuff here.
}
std::function<void(int)> func;
};
int main()
{
auto find3 = [](int arr)
{
if (arr == 3)
return_from_caller; // making up syntax here.
};
Foo foo(find3);
};
有没有办法用lambda做到这一点?
不完全像宏,但您的 lambda,而不是返回bool
,可以throw
特殊异常(例如,类型bool
(
auto check_range
= [](int x) { if ( (x < xmin) || (x > xmax) ) throw bool{false}; };
而函数myFunc()
可以截获这种特殊类型
bool myFunc (int myint)
{
try
{
check_range(myint);
int anotherint = myint + 2;
check_range(anotherint);
return true;
}
catch ( bool e )
{ return e; }
}
对于一个check_range()
电话,这是(我想(一个坏主意;如果你有很多电话,我想可能会很有趣。
以下是完整的工作示例
#include <iostream>
constexpr int xmin{1}, xmax{5};
auto check_range
= [](int x) { if ( (x < xmin) || (x > xmax) ) throw bool{false}; };
bool myFunc (int myint)
{
try
{
check_range(myint);
int anotherint = myint + 2;
check_range(anotherint);
return true;
}
catch ( bool e )
{ return e; }
}
int main ()
{
std::cout << myFunc(0) << std::endl; // print 0
std::cout << myFunc(3) << std::endl; // print 1
std::cout << myFunc(7) << std::endl; // print 0
}
没有比只使用 lambda 的返回值然后从调用函数return
更好的方法了。 宏就是为此而做的。
正如C++的那样,这是退出函数的惯用方式,该函数使用另一个条件来确定是否退出。
不是C++11,但人们已经破解了C++2a协程来基本上做到这一点。
它看起来有点像:
co_await check_range(foo);
其中co_await
关键字指示在某些情况下,此协程可能会提前返回并显示不完整的结果。 在您的情况下,此不完整的结果将是不可恢复的错误。
我看到的玩法是可选的,并且需要使用共享 ptr,但在标准化之前情况可能会有所改善。
- 从函数返回const char*数组
- 检查函数返回类型是否与STL容器类型值相同
- 从 c 或 cpp 系列子函数返回到主函数
- 从函数返回任意简单类型的数据
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 从 C++ 中的函数返回数组地址问题
- VirtDisk.h QueryChangesVirtualDisk() 函数返回 RangeCount 为 0
- 为什么glGetSubroutineIndex为不同的函数返回相同的值?
- 在 c++ 中将函数返回类型指定为模板参数
- 从封装在对象中的函数 C++ 返回时为空的列表
- 为什么向量内部的指针在从函数返回时会发生变化?
- 函数返回的 rvalue 引用(表达式)是 xvalue - 但没有标识?
- 程序中的布尔函数返回输入的范围无论如何都是无效的
- 寿命延长从函数返回引用
- 程序不向函数返回值
- 字符串函数返回奇怪的值
- 类的大问题,以及从空函数c++返回
- 为什么在尝试测量函数返回所需的时间时,我的运行时编号是错误的?
- C++二叉搜索树模板从函数返回节点
- NVCC 错误:string_view.h:constexpr 函数返回是非常量