2017-07-03 21 views
1

これまでに質問されたことがありますが、まだ回答を見つけるのに苦労しています。C++で文字列と異なるベクトルデータ型のマップを返す

mapのとvectorのメソッドを返そうとしています。

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); 

のエラーを取得しています:私はこれは私がこれまでに行ったことある二つのベクトルstd::vector<Eigen::MatrixXd> samplesstd::vector<std::string> sample_names

を持っていますこの方法ではvectorである。もし私がまたはEigen::MatrixXdを追加すると、彼らは両方を手にすることができません。私はboost::anyを使うことができると知っていますが、コンパイルする必要のある余分なライブラリ(?)であり、C++は動的に型付けされていません。

余分なライブラリを持たないことでこれを行う方法はありますか?

アップデート-1:

私は私が行うことができると思うもう一つの方法は、コンストラクタでvector<Eigen::MatriXd> samples & vector<std::string> smaple_namesのプライベート変数を持っているし、2つの同じベクトル型のメソッドget_samples()get_sample_names()を作成し、その後this->samples = samplesのようなものを使用することですthis->sample_name。これは唯一の他の方法ですか?

更新-2:

C++ 17であるstd::anyように見えます - http://en.cppreference.com/w/cpp/header/anyany 1つ:興味がある。

アップデート-3:すべてのマップを使用する理由

If anyone is looking for the answer it's at

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

+0

は、「私は、余分なライブラリを持っていないことによってこれを行うことができます方法はありますか?」自分で 'std :: any'と書くこともできます。:P私はそれがなくても可能ではないと思います。あなたはデザインを考え直したいかもしれません。 – Rakete1111

+0

@ Rakete1111私の更新が見えますか? – Akshay

+0

@ Rakete1111どうすればいいですか? – Akshay

答えて

2

でreturn文を置き換えることができ、私は(std::anyことに同意します:ここで

は、関数は次のようになります。またはboost::any)は、この状況では少し過剰です。 std::variant(またはboost::variant)は、ここでは2つのタイプを保存することが正確に分かっているので、ここではより良い選択となります。

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知るために、インデックスをチェックする必要があります。

+0

構造体を使う考えは良いですが、なぜそれらの2つのマップを返しますか?構造体を直接返すだけで、両方のメンバを埋めることができます(そして 'index'メンバをスクラップします)。 –

+0

@ArthurTacca OPが文字列キーでOPにアクセスしたいと思うので、地図が必要です。それが必要ない場合、 'std :: pair'も働いていました。 – Rakete1111

+0

私は明日これを試して、あなたに知らせるつもりです。 Rakete1111 @助け – Akshay

1

?代わりにstd::pair<std::vector<std::string>, std::vector<Eigen::MatrixXd>>を使用できます。あなたがC++ 11を使用している場合

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); 
} 

、あなただけの

return {sample_names, samples}; 
+0

あなたはどのようにコンテンツを返すのですか? – Akshay

+0

私は答えをどのように編集して編集しましたか? –

+0

私はこれをやってみることができなければ、実際に鍵ペアとやりたかったのです。 +1のために助けてください – Akshay

関連する問題