1

我需要构建一个可以具有多种类型的类的向量,如下所示:

#include <variant>
#include <vector>
#include "Field.h"

using namespace std;

int main()
{
    variant <int, float> v;
    vector <variant<Field<int>, Field<string>, Field<float>>> fdList;
    fdList[0].getName();
}

这是头文件Field.h

#pragma once
#include <string>
#include <vector>

using namespace std;

template<class T>
class Field
{
public:
    Field();
    Field(string);
    void setName(string);
    string getName();
    bool isPrime();
    void toPrime();
    void toForeign(Field);
    ~Field();

private:
    string FD_Name;
    vector <T> records;
    bool isPrimeK = false;
    string message;
};

template<class T>
string Field<T>::getName()
{
    return FD_Name;
}

当我尝试访问getName()函数时,Visual Studio 不断给我以下消息错误:

E0135 类 "std::variant<Field, Fieldstd::string, Field>" 没有成员 "getName"
C2039 'getName': 不是 'std::variant<Field,Fieldstd::string,Field>' 的成员

但它工作得很好,如果我这样定义我的向量:

vector <Field<int>> fdList;
fdList[0].getName();

我怎样才能解决这个问题?

4

2 回答 2

1

调用 on 方法variant不会自动调用variant. 您必须visit使用主动替代并调用相应的处理程序。在您的情况下,由于您想以相同的方式处理所有潜在的有效替代方案,您可以执行以下操作:

std::visit([](const auto& field) {
  field.getName();
  // ...
}, fdList[0]);

或者,您可以将其包装在以下内容variant中:

struct AnyField {
  string getName() const {
    return std::visit([](const auto& field) { return field.getName(); }, v);
  }

  std::variant<Field<int>, Field<string>, Field<float>> v;
};

然后像你想要的那样使用它们:

vector<AnyField> fdList;
fdList[0].getName();
于 2020-08-28T02:20:57.323 回答
1

对于标准库的任何问题,我建议您先查看文档。您可以在此处查看如何使用std::variant.

简而言之,您无法访问您std::variant喜欢的内容,因为它的类型是std::variant而不是您存储在其中的类型。对于您的情况,我认为您可能想先通过调用std::variant::index()方法检查里面的内容,然后通过调用获取值std::get

于 2020-08-28T02:16:13.667 回答