在C ++中返回字符串和不同向量数据类型的映射

时间:2017-07-03 10:55:18

标签: c++ vector

我之前已经问过这样的问题,但我仍在努力寻找答案。

我正在尝试返回map stringvector的方法;我有两个向量std::vector<Eigen::MatrixXd> samplesstd::vector<std::string> sample_names

这是我到目前为止所做的:

std::map<std::string, std::vector> FileReader::get_data() {
    std::map<std::string, std::vector> content;

    std::vector<Eigen::MatrixXd> samples;
    std::vector<std::string> sample_names;

    for (auto i : list_dir()) {
        if (contains_number(i)) {
            samples.push_back(load_csv(location + "/" + i));
            sample_names.push_back(i);
        }
    }

    content["samples"] = samples;
    content["sample_names"] = sample_names;

    return content;
}

显然,我收到错误

error: type/value mismatch at argument 2 in template parameter list for 'template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map'
         std::map<std::string, std::vector> get_data(void);

因为我在方法中没有vector的数据类型。如果我添加stringEigen::MatrixXd,则两者都无法齐头并进。我知道我可以使用boost::any,但它是一个需要编译的额外库(?),而且C ++不是动态类型的。

有没有办法可以通过没有额外的库来做到这一点?

更新-1:

我认为我能做的另一种方式是在构造函数中有一个vector<Eigen::MatriXd> samples&amp;的私有变量。 vector<std::string> smaple_names并创建两个相同向量类型get_samples()get_sample_names()的方法,然后使用this->samples = samplesthis->sample_name之类的方法。这是唯一的另一种方式吗?

更新-2:

看起来std::any在C ++ 17中 - http://en.cppreference.com/w/cpp/header/any。如果any一个:p感兴趣。

更新-3:

  

如果有人在

寻找答案      

https://stackoverflow.com/a/44896365/3782963

2 个答案:

答案 0 :(得分:2)

我同意std::any(或boost::any)对于这种情况有点矫枉过正。 std::variant(或boost::variant)在这里是更好的选择,因为您确切地知道要存储的两种类型。

如果您不想使用任何其他库(如Boost)并且无法访问C ++ 17,您可以尝试在虚拟实现中模拟std::variant(如果您不能写一个完整的)。类似的东西:

struct data {
    // constructors...

    std::vector<Eigen::MatrixXd> samples;
    std::vector<std::string> names;
    int index = -1;
};

然后,您可以将数据存储在std::map<std::string, data>

std::map<std::string, data> content;
content.emplace(std::make_pair("samples", data{samples, 0}));
content.emplace(std::make_pair("sample_names", data{sample_names, 1}));

然后您只需要检查索引以了解您必须使用哪个std::vector

答案 1 :(得分:1)

为什么要使用地图?您可以改为使用parent.setOnItemSelectedListener(new OnItemSelectedListener(){ public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) { final String text = spinner.getSelectedItem().toString(); ...rest of the code fro comparison... } });

这是函数的样子:

std::pair<std::vector<std::string>, std::vector<Eigen::MatrixXd>>

如果您使用的是C ++ 11,则可以使用

替换return语句
std::pair<std::vector<std::string>, std::vector<Eigen::MatrixXd>> FileReader::get_data() 
{
    std::vector<Eigen::MatrixXd> samples;
    std::vector<std::string> sample_names;

    for (auto i : list_dir()) {
        if (contains_number(i)) {
            samples.push_back(load_csv(location + "/" + i));
            sample_names.push_back(i);
        }
    }

    return std::make_pair(sample_names, samples);
}