我有一些具有不同参数的函数(在此示例中很简单):
int addNums(int a, int b) {
return a + b;
}
int squareNum(int a) {
return a * a;
}
我有一个模板类action
,它具有一个函数指针,该指针最终将指向以上任一函数:
template<class T>
class action {
public:
std::string descriptionOfAction;
T functionPtr;
};
我有一个类user
,应该具有某种形式的action
s的容器:
class user {
public:
std::string name;
//container of actions
};
在main
中,我定义并初始化了两个action
以与上面列出的前两个功能相对应:
action<int(*)(int, int)> addAction;
addAction.descriptionOfAction = "Add two numbers together";
addAction.functionPtr = addNums;
action<int(*)(int)> squareAction;
squareAction.descriptionOfAction = "Square a number";
squareAction.functionPtr = squareNum;
现在我要将这两个action
都插入到user
s的action
s容器中:
user aUser;
aUser.name = "User's Name";
//insert "addAction" and "squareAction" to user's container of actions
由于模板,这些action
不是相同的类型。是否有现有的容器来容纳这些容器?如果没有,是否可以在没有模板的情况下做类似的事情?理想情况下,当user
“使用”其容器中的action
之一时,应删除action
。
这里的问题是函数具有不同的arity(即参数数量)。
将函数放入某个容器并不是什么大问题。您总是可以将函数放到std::vector<void*>
中(编译器不在乎),但是然后呢?有什么计划?
您还需要将函数arity添加到同一容器,因此它将转换为std::vector<std::pair<void*, unsigned int>>
(函数指针+ arity)。这会自动使您的操作添加变得复杂,因为您显然不想手动指定Arity,并且您希望将其自动化以避免任何人为错误。此[[will涉及模板。此外,您将需要手动检查Arities并传递适当数量的参数。这也容易出错。
struct my_function_interface {
virtual int operator()(<all your parameters here>) = 0;
};
然后根据该界面定义您的操作。这是一个经典的OOP解决方案,可以抽象出所有问题。而且,由于您的所有检查和特殊功能调用都不是免费提供的,因此很有可能会表现得更好。在这里,您将有一个虚拟函数调用。
void*
。指向函数的指针与指向变量的指针不同。如果要在一个变量中存储多种类型,请使用std::variant
(如果可以使用C ++ 17;否则请使用union
)。