【发布时间】:2021-06-07 22:48:02
【问题描述】:
我想知道是否可以将 lambda 的整数参数作为其模板参数传递给嵌套模板 lambda。如果可能,那么使用模板 lambda 会带来很多好处。 例如,使用模板 lambda 是一件尴尬的工作。考虑
auto foo=[]<int N>(){
return N;
};
std::cout<<foo.operator()<5>();
在这里,当我们调用 lambda foo 时,我们必须使用模板参数 <5> 调用其原生 operator(),然后由另一个 () 调用它。
所以,如果我们可以设计一个 lambda 来传递一个普通的整数参数,并且 lambda 在内部调用它的本地模板 lambda 并完成工作,那么它就可以省去所有这些尴尬。我设计了这个简单的 lambda 来将参数 N 转换为其本机模板 lambda 的参数。但是我被困在如何调用这个模板 lambda 上。
auto foo=[](int N){
auto f=[]<int N>(){
return N;
};
return f.operator()<N>(); //this cannot compile!
};
我的问题是如何在foo 中调用这个f?或者这个想法完全不可能,因为模板参数要求N 是 constexpr 或 compile-time-constant?
感谢cigien闪电般的快速回复!好像
这个想法完全不可能,因为模板参数要求
N是 constexpr 或 compile-time-constant
除了Chris 建议的可能解决方法之外,我尝试使用std::integral_constant 来解决我原来的template-lambda-invoking-awkwardness。这是我能走多远:
#define constInt(N) integral_constant<int, N>{}
auto foo=[]<int N>(std::integral_constant<int, N>&& n){
auto f=[](){
return array<int, N>{};
};
return f();
};
auto ary1=foo(integral_constant<int, 5>{});
auto ary2=foo(constInt(5));
static_assert(is_same_v<decltype(ary1), array<int, 5>>);
static_assert(is_same_v<decltype(ary2), array<int, 5>>);
通过使用宏constInt,它节省了一点打字工作。那么我的问题是:
这是我们可以通过模板 lambda 调用实现的最佳效果吗?如果模板参数是我们无法利用std::integral_constant 的类型怎么办?
根据Davis 使用标签的建议,我将我的问题重新表述为以下具体任务:
**创建一个 lambda 以返回一个 std::array<T,N>
这是通常的 lambda:
auto createArray=[]<typename T, size_t N>(){
return array<T, N>{};
};
但是用模板参数调用它是一种尴尬的方式:
auto ary4=createArray.operator()<string, 5>();
static_assert(is_same_v<decltype(ary4), array<string, 5>>);
我们可以通过使用std::itegral_constant 之类的普通参数来避免使用这个.operator()<string, 5> 吗?例如,createArray(class_tag<string>{},integral_constant<size_t, 5>{});
那我们应该如何实现这个class_tag呢?
事实证明这是一项非常简单的任务,这是我的实现演示:
template<typename T>
struct class_tag{};
auto createArray2=[]<typename T, size_t N>(class_tag<T>&&, integral_constant<size_t, N>&&){
return array<T, N>{};
};
auto ary5=createArray2(class_tag<string>{}, integral_constant<size_t, 5>{});
static_assert(is_same_v<decltype(ary5), array<string, 5>>);
所以,我想它在下面所有伟大的 cmets 的帮助下解决了我的问题。谢谢大家!
【问题讨论】:
-
“这个想法完全不可能,因为模板参数要求 N 是 constexpr 或 compile-time-constant?”。目前,是的。
-
如果是这样,是否有任何解决方法可以解决问题?
-
您可以将
N当作std::integral_constant。我不知道这是否是您正在寻找的那种技巧。 -
任何可以作为模板参数的东西(甚至是模板)都可以包装在标签类模板中(如果不是
std::integral_constant)。 -
任何可以作为模板参数的东西(甚至是模板)都可以包装在标签类模板中(如果不是 std::integral_constant)。你能举个例子吗这样做?例如,我想创建一个简单的 lambda,只返回 array
。能避免模板 lambda 调用的尴尬吗?