【问题标题】:C++: Container of different typesC++:不同类型的容器
【发布时间】:2020-05-30 20:45:19
【问题描述】:

我有一些带有不同参数的函数(对于这个例子来说很简单):

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,它应该有某种形式的actions 容器:

class user {
public:
    std::string name;

    //container of actions
};

main中,我定义并初始化了两个actions来对应上面列出的前两个函数:

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;

现在我想将这两个actions 插入到users 的actions 容器中:

user aUser;
aUser.name = "User's Name";
//insert "addAction" and "squareAction" to user's container of actions

因为模板,这些actions 不是同一类型。是否有现有类型的容器来容纳这些?如果没有,有没有办法在没有模板的情况下做类似的事情?理想情况下,当 user 在其容器中“使用”其中一个 actions 时,应该删除 action

【问题讨论】:

  • 当这些函数有不同的参数列表时,您希望如何使用它们?假设你可以做你想做的,用户怎么知道使用哪个参数列表?
  • std::variant 呢?如果你可以使用 C++17。
  • 在更原始的方法上,模板化标记联合..

标签: c++ templates containers function-pointers


【解决方案1】:

这里的问题是函数有不同的arity(即参数的数量)。

将函数放入某个容器中并不是什么大问题。您总是可以将您的函数放入std::vector&lt;void*&gt; (编译器不在乎),但是... 什么?有什么计划?

您还需要将函数 arity 添加到同一个容器,因此它会转换为 std::vector&lt;std::pair&lt;void*, unsigned int&gt;&gt;(函数指针 + arity)。这会自动使您的操作添加复杂化,因为您显然不想手动指定 arity,并且您需要自动执行此操作以避免任何人为错误。这涉及模板。此外,您将需要手动检查参数并传递适当数量的参数。这也容易出错。

最简单的方法是定义一些

struct my_function_interface {
    virtual int operator()(<all your parameters here>) = 0;
};

然后根据该界面定义您的操作。这是一个经典的 OOP 解决方案,可以抽象出你所有的问题。此外,它很可能会更高效,因为您的所有检查和特殊功能调用都不会免费提供。在这里,您将有一个虚拟函数调用。

【讨论】:

  • 感谢您的回复以及向我介绍arity。上过 3 个学期的 C++ 课程,我觉得有点轻视,直到现在我才听说过。
【解决方案2】:

不要将指向函数的指针存储为void*。指向函数的指针与指向变量的指针不同。

如果你想在一个变量中存储多种类型,如果你可以使用 C++17,请使用std::variant,否则使用union,如果你不能。

【讨论】:

  • 指针之间绝对没有区别。指针是指针。无论是函数、变量还是计算机内存中您想要的任何其他内容。重要的是你用那个指针做什么。
猜你喜欢
  • 2011-06-04
  • 1970-01-01
  • 1970-01-01
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多