【发布时间】:2019-01-07 14:59:46
【问题描述】:
我想将函数存储在有序集合中,然后将它们全部应用于某个集合,这将导致获得大量修改的值,存储在另一个集合中。我最初的尝试包括创建一个上述函数的std::tuple,并尝试获取将所有这些函数应用于某个类型的结果类型(std::invoke_result):
int main() {
auto multiply = [](const auto arg){ return arg * arg; };
auto change = [](const auto arg){ return std::vector{arg}; };
auto to_string = [](const auto arg){ return arg.size() + " size"; };
auto functions = std::make_tuple(multiply, change, to_string);
std::vector<int> source{1, 2, 3, 4};
using f_type = decltype(functions);
using last_type =
std::tuple_element_t<std::tuple_size_v<f_type> - 1, f_type>;
using result_type =
std::invoke_result_t<last_type, /* size - 2 ret type and so on */>;
/*
* result_type is the type of applying *multiply* to int (type of *source*),
* then applying *change* to the result of *multiply* and then applying
* *to_string* to the result of *change*. Should be std::string.
*/
std::vector<result_type> results{};
}
问题是std::invoke_result_t 的第二个template 参数需要一个类型,该类型将传递给last_type 类型的对象的调用运算符。这需要在最后一个元素的返回类型之前扣除一个,等等(可能有很多函数)。
我最终想要实现的是实现 Java 的流库(这个例子相当于链接 3 个map 函数)。我还将持有额外的enums,它将指示下一个元素是map、filter 还是任何其他受支持的函数,因此不会混淆该函数应该做什么——现在的问题是从这样的逻辑开始。
有没有办法获得链接任意数量的函数的返回类型,其中类型传递给它知道的第一个?
或者我的设计有太多缺陷,我宁愿重新开始,遵循完全不同的逻辑?
免责声明 - 我很清楚C++20(希望)rangesV3 即将推出。我试图模仿他们的行为(有一些小的变化)。我也知道boost::adapters - 他们的用法让我不满意,而且我想尝试简单地实现类似的东西。
【问题讨论】:
-
你考虑过类似
using ResultType = decltype(to_string(change(multiply(source[0]))));的东西吗? -
@lubgr 否,因为存储在
std::tuple中的这些函数的数量可能非常高,而且并不总是已知的。我正在寻找一个通用的解决方案 - 给你一个std::tuple并且你需要使用它(可能以template函数中参数包的std::tuple的形式)。我很想在某种折叠表达式中迭代元组,并通过source[0]指定第一个函数的参数,但我无法实现这样的想法。