Function template accept and return different lambdas(函数模板接受并返回不同的lambdas)
问题描述
我的函数GetThing
如下:
auto GetThing(size_t index, auto&& l1)
{
return l1;
}
auto GetThing(size_t index, auto&& l1, auto&&... rest)
{
if (index == 0)
return l1;
return GetThing(index - 1, rest...);
}
我希望它也能够处理不同的lambdas,同时能够处理其他类型(即非lambdas、非函数,如int
和...),如
std::cout << GetThing(1, 2, 3, 4); //works, return 3
std::cout << GetThing(1, [] {return 0; },
[] {return 1; }, [] {return 2; },
[] {return 3; } )(); //nope
但这里的问题是lambda是不同类型的,因此递归函数会演绎为不兼容的返回类型,所以我似乎不得不这样使用std::function
,但它很难看。
std::cout << GetThing(1, std::function{ [] {return 0; } }, std::function{ [] {return 1; } }, std::function{ [] {return 2; } }, std::function{ [] {return 3; } })();//works
解决此问题的任何可能方法,例如,如果存在重载的operator()
,则它会自动将类型强制为std::function
?
编辑:我知道无捕获的lambdas可以转换为函数指针,但如何在模板中没有std::decay
的情况下推导出它?因为我仍然希望将其他类型作为引用进行处理
EDIT2:我收到了一些使用std::variant
的答案,我在想,除了lambda,参数类型应该是相同的,例如。std::variant<int, int, int>
。可以向GetThing
添加重载,这样当std::variant
持有相同类型时,它将返回该类型的内容,否则(接收lambdas的情况)将返回std::function
推荐答案
您可以将函数存储在变量数组中。当然,这也带来了一些开销。但这使函数也可以使用捕获的变量。
这使您能够从这样的函数集合中选择一个函数,并使用给定的参数执行它,如下所示:
template < typename ARR_T >
struct Collect
{
template < typename ... T >
Collect( T&&...args ): arr{std::forward<T>(args)...}{}
ARR_T arr;
using VARIANT_T = ARR_T::value_type;
VARIANT_T& operator[]( size_t index) { return arr[index]; }
};
template < typename ... T >
Collect( T&& ... args ) -> Collect< std::array< std::variant<T... >, sizeof...(T) >>;
template < typename C, typename ... PARMS >
auto GetThing( size_t index, C&& c, PARMS&&... parms )
{
return std::visit( [ &parms...]( auto&& func)
{
return func(std::forward<PARMS>(parms)...);
}, c[index]);
}
int main()
{
std::cout << GetThing( 2, Collect( []( int, double) {return 0; }, []( int, double) {return 1; }, []( int, double) {return 2; }, []( int, double) {return 3; }), 1,5.6)<< std::endl;
int y = 8;
double d = 9.99;
std::cout << GetThing( 0, Collect( [y,d]( int, double) {return d*y; }, []( int, double) {return 1.; }, []( int, double) {return 2.; }, []( int, double) {return 3.; }), 1,5.6)<< std::endl;
}
在本例中GetThing
还获取用于调用lambda的函数参数,因为调用使用std::visit
。如果您只想选择该函数(&Q;),您将获得std::variant
(如果您喜欢),并且可以自己调用该函数。
auto func = Collect( []( int i, double d) {return d+i; }, []( int i, double d) {return d*i; }, []( int i, double d) {return d-i; } )[2];
std::cout << std::visit( []( auto&& f) { return f( 9, 7.77 ); }, func ) << std::endl;
}
这篇关于函数模板接受并返回不同的lambdas的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:函数模板接受并返回不同的lambdas


基础教程推荐
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- C++,'if' 表达式中的变量声明 2021-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 设计字符串本地化的最佳方法 2022-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01