函数参数可以乘法类型吗?

Can a function argument be multiply typed?

本文关键字:类型 参数 函数      更新时间:2023-10-16

我很确定答案是否定的,但由于它会很可爱,我还是会问这个问题。

例:

class Serializable
{
public:
  virtual void serialize() = 0;
};
class Unserializable
{
public:
  virtual void unserialize() = 0;
};
class A : public Serializable
{
public:
  virtual void serialize()
  {
  }
};
class B : public A, public Unserializable
{
public:
  virtual void unserialize()
  {
  }
};

现在,有没有办法创建一个带有一个参数的函数,该参数既是可序列化的实例,是不可序列化实例,以便可以传递类 B 的对象(当然,无需引用派生类型 B)? 像这样:

void readAndWrite(Serializable_Unserializable& object);

模板方式:

template <typename T>
std::enable_if_t<std::is_base_of<Serializable, T>::value
              && std::is_base_of<Unserializable, T>::value>
void readAndWrite(T& object)

当然,如果可以修改B(以及必须继承两者的任何其他派生类型)以派生继承两个接口的单个接口,并且不介意虚拟继承:

class Serializable_Unserializable:
    public virtual Serializable,
    public virtual Unserializable

还必须将虚拟继承添加到 A 和任何其他继承两个基接口之一的类中,并且可以由同时继承组合接口的类继承。

class A: public virtual Serializable

现在,您可以将B更改为:

class B: public A, public Serializable_Unserializable

它可以传递给您的void readAndWrite(Serializable_Unserializable& object).

如果没有这些更改,我认为您无法定义一个函数,该函数仅接受继承两个单独接口的对象,但允许在运行时确定类型。如果后者不是硬性要求,那么模板将是一种替代方案。

如果您

不介意搜索对象的 VMT 以查看是否支持Unserializable的运行时开销,则可以考虑使用 dynamic_cast

void readAndWrite(Serializable& object)
{
    Unserializable *uobject = dynamic_cast<Unserializable*>(&object);
    if (uobject) {
        // supported ...
    } else {
        // not supported ...
    }
}