首页 > 解决方案 > 我正在研究使用 std::variant 的异构列表。有没有办法每次都用一组自定义的 std::variant 类型来初始化它?

问题描述

std::variant...或在源代码中快速更改类型。

下面是列表本身及其容器元素的头文件中的代码。

// HVector.hh
class HVector: public std::vector<HVElem>
{
public:
    HVector();
    void push(std::variant<Party, Loot> newData);
    void show();
};

//HVElem.hh
class HVElem
{
public:
    HVElem( std::variant<Party, Loot> newData );
    ~HVElem();
    std::variant<Party, Loot> getData();
private:
    std::variant<Party, Loot> data;
};

我担心当我必须更改HVector可以采用的类型集时,我将手动检查每个std::variant.

  1. std::variant在这种情况下使用这只是一个坏主意吗?
  2. 如果是,我应该使用模板还是std::any
  3. 有没有办法HVector在初始化期间存储类型并传递它们?
  4. 重构工具是解决问题的方法吗?

标签: c++oopstd

解决方案


  1. 在这种情况下,这只是使用 std::variant 的一个坏主意吗?

上下文太少,所以我不得不假设您正在使用std::variant,因为这std::variant是您需要的。

  1. 如果是,我应该使用模板还是 std::any?

std::any是为了一些非常不同的东西。std::variant适用于有限的一组类型,std::any适用于任何类型。根据您的实际需要选择一个或另一个,而不是基于更容易的重构等。

  1. 有没有办法在初始化期间存储类型并将它们传递给 HVector?

您可以使用别名:

using my_variant = std::variant<Party,Loot>;

如果您愿意,可以制作类模板并提供变体类型作为参数:

template <typename T>
class HVector: 
{
public:
    HVector();
    void push(T newData);
    void show();
};

这将更加灵活,但并不是真正必要的。

  1. 重构工具是解决问题的方法吗?

一旦有了别名my_variant并在整个代码中一致地使用它,您只需在一个地方更改它。

PS:从标准容器公开继承通常不是一个好主意。它可以做对,但你必须小心。我允许自己在上面的示例中简单地忽略该部分,因为它仅与问题相关。

PPS: 的情况std::variant有点类似于std::pair。我的意思是通用性是以没有意义的名字为代价的。即使您只在代码中的一个地方使用该变体,您也应该给它一个有意义的名称。阅读您的代码时,我不明白 a 到底是什么std::variant<Party,Loot>。与告诉我有关含义的别名不同。我不知道什么是好名字。my_variant当然不是一个。


推荐阅读