什么是C ++的Java通配符?

时间:2019-11-15 18:43:01

标签: c++ templates generics

在Java中,如果您有类似的类:

class Box<E>
{
    some code
}

您可以使用通配符执行以下操作:

Box<?> someBox;
someBox = new Box<Integer>();
someBox = new Box<Double>();

在C ++中有没有办法做到这一点?

用更好的话来说,如何在C ++中声明一个可以容纳Box<Integer>Box<Double>Box<WhateverDataTypeHere>的变量?

4 个答案:

答案 0 :(得分:6)

template <typename T> class Box应该从非模板基继承(例如class BasicBox)。

然后指向BasicBox的指针可以指向派生模板的专业化对象:

BasicBox *someBox = new Box<int>;

或者,因为在现代C ++™中应该避免手动管理内存,所以使用智能指针将是一个更好的主意:

std::unique_ptr<BasicBox> someBox = std::make_unique<Box<int>>();

答案 1 :(得分:1)

除了HolyBlackCat's excellent answer外,我还应该提到您还有其他几个选项可以达到类似的效果。

如果您有一些类的子集,则可以像这样从相同的基础继承它们:

class Base {

};

class Derived1 : public Base {

};

class Derived2 : public Base {

};

然后,您可以像这样创建Box

Box<std::uinque_ptr<Base>> genericBox;

genericBox现在可以容纳任何派生类,尽管由于C ++的工作方式,您可能需要通过指针,引用或std::unique_ptr来保存它。因此,这有点混乱,但是可以。

另外,我应该指出,对于intdouble这样的类型,使用此方法将无效,因此,如果您需要使用这些类型,则可能没有用。

如果可以访问,最好使用std::variant。这将允许您存储一组特定的类型:

Box<std::variant<int, double>> genericBox;

genericBox可以容纳doubleint

如果您没有直接访问std::variant的权限,那么还有一个boost::variant基本上是相同的。或者,如果您都无法访问,则可以选择union

union GenericType {
    int myInterger;
    double myDouble;
};

Box<GenericType> genericBox;

当然,std::variantboost::variant更好,但是如果您处在没有这些的情况下,这将对您有用。

现在,这些选项仅在您提前知道要存储的类型时才有效。如果您不知道,可以选择std::any

Box<std::any> genericBox;

std::variant一样,还有一个boost::any。如果您出于某些疯狂原因不得不真的,也可以implement it yourself。但是我不建议您这样做,除非您出于教育目的之类。

答案 2 :(得分:0)

在C ++中,这称为模板化

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="LimitedString">
    <xs:restriction base="xs:string">
      <xs:maxLength value="50"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:element name="BRSTAG">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" name="INSTRUMENTS">
          <xs:complexType>
            <xs:sequence>
              <xs:element minOccurs="0" maxOccurs="unbounded" name="INSTRUMENT"> 
                <xs:complexType>              
                  <xs:sequence>
                    <xs:element minOccurs="0" name="CUSIP" type="xs:string"/>

用您想要的任何类型替换T。 Here's有关该主题的一些出色文档

答案 3 :(得分:-1)

嗯,这不是某人想要的东西,但是您可以将指针用于诸如int之类的基本类型 对于类,您可以执行此操作,或者对可以使用的所有类型使用一些基类。