我正在处理使用 std::variant 的异构列表。有没有办法每次使用 std::variant 的一组自定义类型来初始化它?

I'm working on heterogenous list that uses std::variant. Is there a way to initialize it every time with a custom set of types for 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 可以采用的类型集时,我将不得不手动完成每个 [=13] 的“<>”中的大量代码更改内容=].

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

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

  1. If yes, should I use templates or std::any?

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

  1. Is there a way to store types and pass them into HVector during initialization?

您可以使用别名:

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

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

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

这会更灵活,但并不是必须的。

  1. Are refactoring tools a solution to the problem?

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

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

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