

std::vectorにEigen::MatrixXdを追加していき, あとからvector内の行列を計算させるプログラムを作りたいのですが,
どうしてもうまくいきません...  
下のプログラムを実行するとこのようなエラーがでます.

[code]

    affine.cpp: In function ‘int main(int, const char**)’:
    affine.cpp:15:12: error: ‘itr’ does not name a type
       for(auto itr = model.begin(); itr != model.end(); ++itr) {
                ^
    affine.cpp:15:33: error: expected ‘;’ before ‘itr’
       for(auto itr = model.begin(); itr != model.end(); ++itr) {
                                     ^
    affine.cpp:15:33: error: ‘itr’ was not declared in this scope
    
[/code]

ソースコードはここからです.

[code]

    #include <iostream>
    #include <vector>
    #include "Eigen/Core"
    
    int main(int argc, char const* argv[])
    {
      std::vector<Eigen::MatrixXd> model;
    
      model.push_back(Eigen::MatrixXd(3, 6));
      model.push_back(Eigen::MatrixXd(6, 5));
    
      Eigen::MatrixXd a(1, 3);
      std::cout << a << std::endl;
    
      for(auto itr = model.begin(); itr != model.end(); ++itr) {
        a *= (*itr);
      }
    
      return 0;
    }
    
[/code]

エラーの解決方法に加えてvectorにMatrixXdをpush_backしても後々大丈夫なのかということも教えていただけるとありがたいです.  
どなたか分かるかたご教示ください.


CC BY-SA 3.0
2017-05-06T15:55:34.540
34494
2017-05-07T00:38:47.367
2017-05-06T16:43:39.323
3605
question
c++
std::vectorとEigen::MatrixXdを用いた行列計算プログラムでのエラー


コンパイラにはg++を使っているようですが、`auto`はC++11から導入されたので、コンパイルオプションに`-std=c++11`が必要です。これがないと、そのようなエラーが出ます。

* * *

> vectorにMatrixXdをpush_backしても後々大丈夫なのか

というのが、動作するのか、という意味なら大丈夫だと思います。vectorはサイズが大きくなる時に、中身のコピーかムーブが起こるので、パフォーマンスが気になりますが、ざっとヘッダーファイルを見たところ、ムーブコンストラクタなどもサポートしているようなので、神経質になる必要はないのかもしれません。

* * *

ちなみに、インスタンスを作って直ぐに `push_back` するのなら、`emplace_back` を使うといいです。

[code]

      model.push_back(Eigen::MatrixXd(3, 6));
      model.push_back(Eigen::MatrixXd(6, 5));
    
[/code]

の代わりに

[code]

      model.emplace_back(3, 6);
      model.emplace_back(6, 5);
    
[/code]

とします。見た目もすっきりしますし、パフォーマンスの改善も見込めます。


CC BY-SA 3.0
2017-05-06T17:43:52.543
34495
2017-05-06T17:43:52.543
3605
34494
answer


ほとんどHidekiさんが回答されていますが、`auto`キーワードは元々ストレージクラスを表すもので、`static`、`extern`、`typedef`、`register`等と同列に扱われていました。

[code]

    auto int i;
    static int j;
    
[/code]

ですので、

>
[code]

>     affine.cpp:15:12: error: ‘itr’ does not name a type
>     for(auto itr = model.begin(); itr != model.end(); ++itr) {
>              ^
>  
[/code]

とエラーで指摘されているように`auto`の後ろには型名が必要でした。

C++11にて[`auto`](https://cpprefjp.github.io/lang/cpp11/auto.html)の意味が変更され自動変数として扱えますが、そのためにはソースコードがC++11であることを明示する必要があるわけです。

なお、後半の

>
[code]

>     for(auto itr = model.begin(); itr != model.end(); ++itr) {
>       a *= (*itr);
>     }
>  
[/code]

は[`std::accumulate`](https://cpprefjp.github.io/reference/numeric/accumulate.html)、[`std::begin`](https://cpprefjp.github.io/reference/iterator/begin.html)、[`std::end`](https://cpprefjp.github.io/reference/iterator/end.html)、[`std::multiplies`](https://cpprefjp.github.io/reference/functional/multiplies.html)、[一様初期化](https://cpprefjp.github.io/lang/cpp11/uniform_initialization.html)を使って

[code]

    a = accumulate(begin(model), end(model), a, std::multiplies<>{});
    
[/code]

と書けます。


CC BY-SA 3.0
2017-05-07T00:38:47.367
34500
2017-05-07T00:38:47.367
4236
34494
answer