【问题标题】:What's a C++ equivalent of Java wildcards?Java 通配符的 C++ 等价物是什么?
【发布时间】:2019-11-15 18:43:01
【问题描述】:

如果你有这样的类,在 Java 中:

class Box<E>
{
    some code
}

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

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

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

换句话说,我如何在 C++ 中声明一个可以容纳 Box&lt;Integer&gt;Box&lt;Double&gt;Box&lt;WhateverDataTypeHere&gt; 的变量?

【问题讨论】:

  • 指向基类类型的指针?
  • Java 代码不是一直向下到变量级别,而是应该做什么? C++ 和 Java 不一样,尝试从 Java 源代码模仿或建模 C++ 代码是不明智的。

标签: c++ templates generics


【解决方案1】:

template &lt;typename T&gt; class Box 应该继承自非模板基(比如class BasicBox)。

那么指向BasicBox的指针可以指向派生模板的特化对象:

BasicBox *someBox = new Box<int>;

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

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

【讨论】:

    【解决方案2】:

    除了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。但我不建议这样做,除非您是出于教育目的或其他目的。

    【讨论】:

      【解决方案3】:

      在 C++ 中称为模板

      template <typename T>
      class Box {
      private:
          T boxcontents;
      }
      

      用你想要的任何类型替换 T。 Here's 一些关于该主题的精彩文档

      【讨论】:

      • 如何获得一个可以容纳Box&lt;int&gt;Box&lt;double&gt; 的变量?
      • @JaMiT 这就像那样工作。您可以拥有多个 box 类型的对象,其中包含您想要的任何模板类型:int、double、float 等。如果您要问如何拥有一个包含多种类型的盒子,您可以创建一个第三类关闭类型 J 来保存两种不同类型的两盒。
      • 您还没有提到作为问题焦点的变量。当然,您可以拥有多个对象,但该问题明确要求使用可以保存不同类型对象的单个变量。如何用你的方案声明这样一个变量?
      • 你可以让变量成为一个模板结构,里面有两个对象吗?我不确定我是否理解这个问题......
      • 请简单地声明someBox,以便问题中的两个分配有效。
      【解决方案4】:

      嗯,这不是某人想要的,但您可以使用指针来表示基本类型,例如 int 对于类,您可以这样做,或者为您可能使用的所有类型使用一些基类。

      【讨论】:

        猜你喜欢
        • 2010-10-06
        • 2011-10-13
        • 1970-01-01
        • 1970-01-01
        • 2017-12-18
        • 2011-01-10
        • 2016-07-26
        • 2010-12-07
        • 2010-11-22
        相关资源
        最近更新 更多