我已经开始使用这种类型的构造,它依赖于 C++20 的 lambda 显式模板参数:
template<typename... Ts>
struct Foo
{
std::tuple<Ts...> bars;
auto get_labels(const std::array<std::size_t,sizeof...(Ts)>& indices) const
{
// construct tuple from bar labels
return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
return std::make_tuple(std::get<Is>(bars).get_label(indices[Is])...);
}(std::index_sequence_for<Ts...>{});
}
};
在 C++17 或 C++14 中是否有相对优雅的方法可以做到这一点?或者我现在应该将 C++20 作为一项要求?
因此,认清您真正需要的是哪个部分非常重要。当您写下以下内容时:
您实际需要的是
Is...
。或者,更一般地说,您实际需要的是一组常量值。在上面的例子中,您接受一个参数index_sequence<Is...>
- 这是一个参数,其类型包含一组常量值。但另一种方法是接受
N
不同的参数,其中第一个参数是 类型integral_constant<size_t, 0>
,第二个参数是 类型integral_constant<size_t, 1>
,依此类推。如果你可以生成这些参数,那么 lambda 部分就变成了请注意,主体是相同的,我只是改变了参数的样子。现在这是一个有效的 C++14 lambda。
因此,问题的其余部分是生成函数模板
with<N>(f)
,该模板调用f(integral_constant<size_t, 0>{}, integral_constant<size_t, 1>{},..., integral_constant<size_t, N-1>{})
允许您调用:而且
with
用 C++14 编写很简单。这实际上只是同样的index_sequence
技巧,但有一个额外的间接寻址(因为您需要将 one 更改index_sequence
为N
integral_constant
s)。可以说,结果看起来也更好 - 它不那么繁忙。无论如何,我更喜欢 C++20 中的这个。一种可能的方法是将序列直接“放置”在类模板中:
一种直接的方法是将 lambda 变成成员函数:
但不确定它是否算得上相对优雅。
解决缺少模板 lambda 问题的一种方法是使用返回 lambda 的模板方法:
演示
这应该从 c++14 开始起作用。
注意:这在某种程度上类似于我在发布之前没有见过的先前答案。也许它更强调了潜在的意图,即制作 lambda 模板,但更加不友好。
因此,如果您可以在自己的环境中使用 c++20,那么它是一个很好的举措。