Apply stateful lambda to integer sequence values(将有状态lambda应用于整数序列值)
问题描述
我正在尝试实现数字文字运算符模板。
#include <string_view>
#include <cstdint>
#include <cmath>
#include <iostream>
#include <boost/mp11/integer_sequence.hpp>
#include <boost/mp11/algorithm.hpp>
using namespace boost::mp11;
template <char... Cs>
[[nodiscard]] constexpr auto operator""_c(){
int weight =std::pow(10, sizeof... (Cs));
// unused, would like to transform it using lambda that mutably captures
// weight
using ints = index_sequence<sizeof... (Cs)>;
// ugly fold way
auto val = ((weight/=10,(int)(Cs-'0')*weight) + ...);
return val;
}
int main(){
std::cout << 0_c << std::endl;
std::cout << 00_c << std::endl;
std::cout << 01_c << std::endl;
std::cout << 123_c << std::endl;
}
这个code适用于简单的情况(正确性并不重要,比如负数),它只是一个例子,但是代码看起来很难看,并且clang会发出多次修改权重的警告,所以我猜代码有错误(未定义或未指定的行为),尽管它似乎可以工作...
现在我想知道有什么方法可以将我使用的ints(它来自Boost::MP11,但同样的东西存在于std::中)转换为有状态的lambda(它修改权重)。
所以我想将<0,1,2>整型转换为<100,10,1>
我想以前有人问过这个问题,但很难搜索。
明确地说:运算符只是一个玩具问题,我真正的问题是如何将整数序列的值映射到有状态的lambda。
如果从问题中还不清楚:我非常乐意使用Boost MP11,但在文档中找不到任何东西。
推荐答案
因此,我想将<;0,1,2&>整数转换为 <;100,10,1>;
首先,您可以将std::index_sequence转换为std::array,然后像往常一样对其执行操作,最后再次将std::array转换为std::index_sequence。
为了让有状态lambda在编译时工作,我们可以接受一个可以返回有状态lambda的函数,然后在内部获取它:
template<std::size_t... Is>
constexpr auto transform_seq(std::index_sequence<Is...>, auto get_op) {
// index_sequence -> array
constexpr auto arr = [op = get_op()]() mutable {
std::array<std::size_t, sizeof...(Is)> arr{Is...};
for (auto& value : arr)
value = op(value);
return arr;
}();
// array -> index_sequence
constexpr auto seq = [&]<std::size_t... Js>(std::index_sequence<Js...>) {
return std::index_sequence<std::get<Js>(arr)...>{};
}(std::make_index_sequence<arr.size()>{});
return seq;
};
然后您可以根据传入的op执行index_sequence转换:
using input1 = std::index_sequence<0,1,2>;
auto gen_op1 = [] {
return [w = 1000](auto x) mutable { w /= 10; return w; };
};
using res1 = decltype(transform_seq(input1{}, gen_op1));
static_assert(std::same_as<res1, std::index_sequence<100, 10, 1>>);
using input2 = std::index_sequence<0,1,2,3>;
auto gen_op2 = [] {
return [b = true] (auto x) mutable { b = !b; return b * 10 + x; };
};
using res2 = decltype(transform_seq(input2{}, gen_op2));
static_assert(std::same_as<res2, std::index_sequence<0,11,2,13>>);
Demo.
这篇关于将有状态lambda应用于整数序列值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:将有状态lambda应用于整数序列值
基础教程推荐
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- 初始化列表*参数*评估顺序 2021-01-01
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- CString 到 char* 2021-01-01
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
