在Java中,如果您有类似的类:
class Box<E>
{
some code
}
您可以使用通配符执行以下操作:
Box<?> someBox;
someBox = new Box<Integer>();
someBox = new Box<Double>();
在C ++中有没有办法做到这一点?
用更好的话来说,如何在C ++中声明一个可以容纳Box<Integer>
或Box<Double>
或Box<WhateverDataTypeHere>
的变量?
答案 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
来保存它。因此,这有点混乱,但是可以。
另外,我应该指出,对于int
或double
这样的类型,使用此方法将无效,因此,如果您需要使用这些类型,则可能没有用。
如果可以访问,最好使用std::variant
。这将允许您存储一组特定的类型:
Box<std::variant<int, double>> genericBox;
此genericBox
可以容纳double
或int
。
如果您没有直接访问std::variant
的权限,那么还有一个boost::variant
基本上是相同的。或者,如果您都无法访问,则可以选择union
:
union GenericType {
int myInterger;
double myDouble;
};
Box<GenericType> genericBox;
当然,std::variant
和boost::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
之类的基本类型
对于类,您可以执行此操作,或者对可以使用的所有类型使用一些基类。