Constexpr lambda argument
Constexpr lambda argument
是否有可能有一个带有 constexpr 参数的 lambda?是否可以使以下示例起作用?
下面提供的ForEach
函数调用给定的 lambda 3 次,索引为 0、1、2:
template <class Func, std::size_t... index>
inline constexpr void ForEach(Func && f, std::index_sequence<index...>)
{
(f(index), ...);
}
template <class Func>
inline constexpr void ForEach(Func && f)
{
ForEach(f, std::make_index_sequence<3>());
}
所以下面的代码
ForEach([](size_t index)
{
std::cout << index << ' ' << std::endl;
});
输出 0、1、2。
但是以下尝试打印元组元素的代码要求index
是一个 constexpr:
auto t = std::make_tuple(1, 2.0, std::string("abc"));
ForEach([&t](size_t index)
{
std::cout << std::get<index>(t) << ' ' << std::endl;
});
因此不编译,请参阅实时示例。是否有可能以某种方式制作index
constexpr?
EDIT1:有一个工作示例,其中lambda参数用作模板参数:
void Set(Tuple& val, size_t index, Variant const& elem_v)
{
mp_with_index<std::tuple_size_v<Tuple>>(
index,
[&](auto I){
std::visit([&](auto const& alt){
if constexpr (std::is_assignable_v<
std::tuple_element_t<Tuple, I>,
decltype(alt)>)
{
std::get<I>(val) = alt;
} else {
throw /* something */;
}
}, elem_v);
});
}
为什么可以编译,而我的示例代码不能?
在此:
ForEach([&t](size_t index)
{
std::cout << std::get<index>(t) << ' ' << std::endl;
});
index
不是一个恒定的表达式。它只是一个变量。函数参数不是连续的。
但是,如果我们稍微调整ForEach
(以与您链接的示例相同的方式工作(:
template <class Func, std::size_t... index>
inline constexpr void ForEach(Func && f, std::index_sequence<index...>)
{
(f(std::integral_constant<std::size_t, index>()), ...);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// instead of just index
}
ForEach([&t](auto index)
{
std::cout << std::get<index>(t) << ' ' << std::endl;
});
然后这是有效的,因为index
不再是size_t
而是针对各种V
的不同std::integral_constant<size_t, V>
实例。该类型如下所示:
template<class T, T v> struct integral_constant { static constexpr T value = v; typedef T value_type; typedef integral_constant type; // using injected-class-name constexpr operator value_type() const noexcept { return value; } constexpr value_type operator()() const noexcept { return value; } //since c++14 };
将std::integral_constant<size_t, V>
转换为size_t
会调用constepxr operator size_t()
,这不涉及从该对象本身读取任何状态(这是一个空类型(,因此它被允许作为常量表达式。
另一种看待它的方式是,我们将值编码在类型(可以作为常量表达式检索(而不是值(不能(中。
相关文章:
- 表示"accepting anything for this template argument" C++概念的通配符
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 可组合的lambda/std::函数与std::可选
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 如何将lambda作为模板类的成员函数参数
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 在 lambda 捕获中声明的变量的类型推导
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 模板函数指针和lambda
- 两组使用lambda函数的大括号
- 使lambda不可复制/不可移动
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 尝试将lambda函数放在队列中时出现一般分配器错误(可能是与unique_ptr有关的错误)
- 将带有unique_ptr的可变 lambda 传递给 const&std::function
- AWS Lambda C++运行时权限被拒绝
- 捕获lambda中的std::数组
- 这 4 个 lambda 表达式之间有什么区别?
- Constexpr lambda argument