gpt4 book ai didi

C++ 递归可变参数 Lambda

转载 作者:可可西里 更新时间:2023-11-01 17:49:13 25 4
gpt4 key购买 nike

在 C++ 中,我们可以有一个递归可变参数模板函数。例如:

template<typename ...H>
void g(){}
template<typename H, typename ...T>
void g(H h,T ...t){
std::cout << h << "\t";
g<T...>(t...);
}

然而,这似乎无法使用 lambda 来完成。我主要关心的两个主要问题是:

  • 如何建立基本案例。
  • 如何使 lambda 既递归又可变。

我知道我可以使用递归 lambda,但看不到使其可变的方法。这种类型的功能是否仅适用于更高级的语言,例如 Javascript?

编辑:到目前为止,这是我想出的:

template<typename C,typename H, typename ...T>
std::function<void(C,H,T...)> f=[](auto&& self,H h,T ...t){
std::cout << h << "\t";
if(sizeof...(t)>0)
self(self,t...);
};

这里的第一个参数是 lambda 本身。但是,主要问题是,为了调用此方法,我需要定义类型 C,但我不确定该怎么做(或者即使可能)。

编辑:更简单的方法是:

auto f = [] (auto&&  self, auto&& h,auto&&... t) {
std::cout << sizeof...(t) << "\n";
if( sizeof...(t)>0 ){
self(self,1);
}
};

int main()
{
f(f,1,2,3,4,5,6);
return 0;
}

但是报错如下:

main.cpp:55:13: error: use of ' [with auto:1 = &; auto:2 = int; auto:3 = {}]' before deduction of 'auto'
self(self,1);
^

最佳答案

C++17 用 Constexpr if 解决了这个问题:

#include <iostream>

auto f = [](auto&&... t){
auto f_impl = [](auto& self, auto&& h, auto&&... t) {
std::cout << sizeof...(t) << "\n";
if constexpr ( sizeof...(t)>0 ){
self(self,t...);
}
};
return f_impl(f_impl, t...);
};

int main() {
f(1,2,3,4,5,6);
}

我还冒昧地将第一个参数 (self) 包装在“父”lambda 中。

使用 if(sizeof...(t)) 作为守卫的问题在于,即使您不会在运行时使用不正确的参数调用 lambda,编译器仍然需要编译带有 sizeof...(t)==0 的表达式 self(self, t...) 失败。

constexpr if 通过在编译时进行检查来解决这个问题,甚至在检查结果为 false 时不编译 block 。在 C++17 之前,条件编译语义(不包括宏)只能使用 SFINAE 或模板特化来实现,这两者都不能仅使用 lambda 来完成。

关于C++ 递归可变参数 Lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49495015/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com