我想问一下,是否有可能为每个算法(如STL)定义多个函数作为输入参数并按从左到右的顺序进行评估?
template <typename Iterator, typename ... Args>
void for_each(Iterator begin, Iterator end, Args ... args) {
// apply functions passed in Args... to range [begin,end)
}
我如何访问Args传递的那些功能?是否只能使用一些模板递归?
答案 0 :(得分:2)
您可以使用以下内容:
#include <iostream>
#include <utility>
#include <algorithm>
template <typename Iterator, typename F1>
void for_each(Iterator begin, Iterator end, F1 f1)
{
std::for_each(begin, end, f1);
}
template <typename Iterator, typename F1, typename... Fun>
void for_each(Iterator begin, Iterator end, F1 f1, Fun... fs)
{
std::for_each(begin, end, f1);
for_each(begin, end, fs...);
}
int main()
{
std::array<int, 5> a = {1,2,3,4,5};
auto f1 = [](int i){std::cout << "f1: " << i << " ";};
auto f2 = [](int i){std::cout << "f2: " << i << " ";};
for_each(a.begin(), a.end(), f1, f2);
}
<强>输出:强>
f1: 1 f1: 2 f1: 3 f1: 4 f1: 5 f2: 1 f2: 2 f2: 3 f2: 4 f2: 5
答案 1 :(得分:1)
你不必为此做一些特殊的模板技巧,只需定义一个递归,如下所示:
template <typename Iterator, typename F>
void recurse(Iterator first, Iterator last, F f) {
if(first != last) {
f(*(first++));
}
}
template <typename Iterator, typename F, typename ...Args>
void recurse(Iterator first, Iterator last, F f, Args ...args) {
if(first != last) {
f(*(first++));
recurse(first, last, args...);
}
}
template <typename Iterator, typename ...Args>
void variadic_for_each(Iterator first, Iterator last, Args ...args) {
recurse(first, last, args...);
}
答案 2 :(得分:1)
我写了一些更通用的东西 - 一些伪代码显示它能做什么:
auto funcs = mk<TupleOfFunctions>(f, g, h); // f, g, h -- callables
// mk is my helper function, I defined it in # Usage # section
funcs(arg) == h(g(f(arg))); // similiar to pipe in shell
// echo arg | f | g | h
用简单的英语,它是班级的模板。它的构造函数可以获取任何数量的callables。调用它的实例将返回由构造函数接收的每个函数转换的参数
并且,因为它可以调用,所以你应该能够将它传递给for_each
。
#include <utility>
// 1 //
template <typename T, typename U>
struct PairOfFunctions: std::pair<T, U> {
using std::pair<T, U>::pair;
template <typename... Args>
auto operator() (Args&&... args) {
return std::pair<T, U>::second(std::pair<T, U>::first(args...));
}
};
template<typename...>
struct TupleOfFunctions;
// 2 //
template<typename T, typename... U>
struct TupleOfFunctions<T, U...>: PairOfFunctions<T, TupleOfFunctions<U...> >{
using PairOfFunctions<T, TupleOfFunctions<U...> >::PairOfFunctions;
TupleOfFunctions(T t, U... u):
PairOfFunctions<T, TupleOfFunctions<U...> >(
t,
TupleOfFunctions<U...>(u...)
)
{}
};
// 3 //
template<>
struct TupleOfFunctions<>{
template <typename T>
T operator() (T t) { // probably not optimal, too lazy to overload
return t;
}
};
PairOfFunctions
- 对的子类:
mk<PairOfFunctions>(f, g)(arg) == g(f(arg));
TupleOfFunctions
- PairOfFunctions
的推广,需要一个或多个callables。
TupleOfFunctions<>
:特殊情况 - 不接受任何函数,返回参数副本。
我的例子是愚蠢的,随意更换它。
// My universal helper
template<template <typename...> class T, typename... Args>
auto mk(Args... args){
return T<Args...>{args...};
}
int main()
{
auto a = mk<TupleOfFunctions>(
[](int a) {return a*2;},
[](int a) {return a + 10;},
[](int a) {return a / 2;}
);
std::cout << a(4) << '\n'; // (4 * 2 + 10) / 2
}