我想设计一种方法来调用许多非常相似的函数中的一个--其中唯一不同的是参数的数量。请记住,这只是我的大问题的一个最小的例子。我有很多函数用于完成不同的任务。每个函数的原型都非常相似--除了它们的参数数量不同。
我希望能够调用一些包装类,我告诉它测试类型,并传递给它一个参数列表(向量),然后它为我整理出其余的参数。
下面是一个可行的设置(不可行的部分被注释掉)。
#include <vector>
#include <map>
#include <functional>
#include <iostream>
enum class test_type {t0, t1, t2, t3, t4, tn};
class tester
{
public:
void run(test_type type, const std::vector<int> &args)
{
func_map[type].func();
};
private:
void function_0() { std::cout << "f0\n"; };
void function_1(int p1, int p2) { std::cout << "f1\n"; };
void function_2(int p1, int p2, int p3) { std::cout << "f2\n"; };
void function_3(int p1, int p2) { std::cout << "f3\n"; };
void function_4(int p1) { std::cout << "f4\n"; };
void function_n(int p1) { std::cout << "fn\n"; };
struct test_info
{
std::function<void()> func; // variadic function std::function<void(...)> ?
int num_params;
};
std::map<test_type, test_info> func_map {
{test_type::t0, {[this]{function_0();}, 0}}
// {test_type::t1, {[this]{function_1();}, 2}}
// {test_type::t2, {[this]{function_2();}, 3}}
// {test_type::t3, {[this]{function_3();}, 2}}
// {test_type::t4, {[this]{function_4();}, 1}}
// {test_type::tn, {[this]{function_n();}, 1}}
};
};
int main() {
tester test;
test.run(test_type::t0, {});
//test.run(test_type::t1, {1, 2});
//test.run(test_type::t2, {1, 2, 3});
//test.run(test_type::t3, {1, 2});
//test.run(test_type::t4, {1});
//test.run(test_type::tn, {1});
return 0;
}
这样就可以了,因为function_0有0个参数,所以它匹配了 std::function<void()>
型。我真的不知道从这里出发的最佳方向是什么。
I 认为 有一个选项可以使用变量 std::function<void(...)>
但读了这本书后,我超出了我的理解范围,而且我对可变模板的理解也不是很好。
所以我的问题是。
std::funtion<void(...)>
在某种程度上?传递 vector
本身的包层,并让他们提取出的 int
值传递给他们的目标函数,例如。
#include <vector>
#include <map>
#include <functional>
#include <iostream>
#include <stdexcept>
enum class test_type {t0, t1, t2, t3, t4, tn};
class tester
{
public:
void run(test_type type, const std::vector<int> &args)
{
func_map[type](args);
};
private:
void function_0() { std::cout << "f0\n"; };
void function_1(int p1, int p2) { std::cout << "f1\n"; };
void function_2(int p1, int p2, int p3) { std::cout << "f2\n"; };
void function_3(int p1, int p2) { std::cout << "f3\n"; };
void function_4(int p1) { std::cout << "f4\n"; };
void function_n(int p1) { std::cout << "fn\n"; };
static void validate(const std::vector<int> &args, size_t needed) {
if (args.size() != needed)
throw std::invalid_argument("wrong number of arguments");
}
using func_type = std::function<void(const std::vector<int> &)>;
std::map<test_type, func_type> func_map {
{test_type::t0,
[this](const std::vector<int> &args){
validate(args, 0);
function_0();
}
},
{test_type::t1,
[this](const std::vector<int> &args){
validate(args, 2);
function_1(args[0], args[1]);
}
},
{test_type::t2,
[this](const std::vector<int> &args){
validate(args, 3);
function_2(args[0], args[1], args[2]);
}
},
{test_type::t3,
[this](const std::vector<int> &args){
validate(args, 2);
function_3(args[0], args[1]);
}
},
{test_type::t4,
[this](const std::vector<int> &args){
validate(args, 1);
function_4(args[0]);
}
},
{test_type::tn,
[this](const std::vector<int> &args){
validate(args, 1);
function_n(args[0]);
}
},
};
};
int main() {
tester test;
test.run(test_type::t0, {});
test.run(test_type::t1, {1, 2});
test.run(test_type::t2, {1, 2, 3});
test.run(test_type::t3, {1, 2});
test.run(test_type::t4, {1});
test.run(test_type::tn, {1});
return 0;
}