对于具有可变数量函数的条件调用的循环



我不希望执行递归调用,而是希望根据循环中的某些条件触发任意数量的函数。如何将method0、method1转换为typename ... methods的变基数?

编辑:由于您不能返回可变数量的类型,我将示例修改为litte。

template <typename method0, typename method1, typename ... Args>
void loop(Args ... args)
{
for (int i = 0; i < iter_max; i++)
{
if (method0::condition(args))
{
method0::call_modify(args);
}
if (method1::condition(args))
{
method1::call_modify(args);
}
//...
}
}
template<typename ... Args>
struct method0
{
static bool condition(Args& ... args)
{
//Trigger condition
}
static void call_modify(Args& ... args)
{
//Perform action on args
}
};

你可以这样做:

#include <iostream>
template<typename ... Args>
struct method0
{
static bool condition(Args& ... args)
{
std::cout << "condition n";
return true;
}
static void call(Args& ... args)
{
std::cout << "calln";
}
};

template <typename... Methods, typename ... Args>
void loop(Args ... args)
{        
auto apply = []<typename m>(auto&... a){
if (m::condition(a...)) m::call(a...); 
};
(apply.template operator()<Methods>(args...), ...);
}
int main() {
loop<method0<int,int>,method0<int,int>>(1,2);
}

输出:

condition 
call
condition 
call

在这种情况下,也许loop也应该引用。我放弃了循环,添加它应该很简单


这是对非变差conditioncall:的稍微简单的情况的答案的旧版本

struct A {
static bool condition(int x) { 
std::cout << "A::condition " << x << "n";
return true;
}
static int call(int) { 
std::cout << "A::calln";
return 42;
}
};
struct B {
static bool condition(int x) { 
std::cout << "B::condition " << x << "n";
return false;
}
static int call(int) { 
std::cout << "B::calln";
return 0;
}
};

你可以让loop用第n个args调用第n个类型conditioncall,如下所示:

template <typename... Methods, typename ... Args>
void loop(Args ... args)
{
auto apply = []<typename m>(auto& a){
if (m::condition(a)) a = m::call(a); 
};
(apply.template operator()<Methods>(args), ...);
}

int main() {
loop<A,B>(1,2);
}

输出:

A::condition 1
A::call
B::condition 2

我设法将463035818_is_not_a_number的答案归纳为循环,并接受了不同数量的输入参数。完整的工作示例:

#include <iostream>
struct method0
{
static bool condition(double &arg1, double &arg2)
{
// Trigger condition
return (arg1 <= arg2);
}
static void call_modify(double &&arg1, double &&arg2)
{
std::cout << "method0!" << std::endl;
arg1 += 1;
}
};
struct method1
{
static bool condition(double &arg1, double &arg2)
{
// Trigger condition
return (arg1 > arg2);
}
static void call_modify(double &&arg1, double &&arg2)
{
std::cout << "method1!" << std::endl;
arg1 -= 1;
}
};
template <int iter_max, typename... Methods>
struct wrapper
{
template <typename... Args>
static void loop(Args &...args)
{
auto apply = []<typename m>(auto&&... a)
{
if (m::condition(a...))
m::call_modify(std::forward<Args>(a)...);
};
for (int i = 0; i < iter_max; i++)
{
(apply.template operator()<Methods>(std::forward<Args>(args)...), ...);
}
}
};
int main()
{
double arg1 = 2.0;
double arg2 = 0.;
constexpr int iter_max = 5;
wrapper<iter_max, method0, method1>::loop<double, double>(arg1, arg2);
}

输出:

method1!
method1!
method0!
method1!
method0!
method1!
method0!
method1!

最新更新