• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:構造体vectorの入れ子のfillの使い方)

構造体vectorの入れ子のfillの使い方

このQ&Aのポイント
  • 構造体vectorの入れ子のfillの使い方について教えてください
  • テンプレート関数で作成したvectorデータのメモリ確保関数を使用した際に、構造体の入れ子vectorのデータのfillの使い方に問題があるようです。正しいfillの使い方を教えてください。
  • Borland C++ 5.5.1 for Win32を使用してビルドした際に、エラーメッセージが表示されました。エラーメッセージについても解決策を教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
noname#144013
noname#144013
回答No.5

こんにちは。 以下、的外れな内容でしたらすみません。 データの初期化が目的なら、構造体 (クラス)のコンストラクタで、メンバデータを 初期化するのは如何でしょうか? 以下は構造体(クラス)定義の一例です。 ================================= //class aa {    //←個人的にはclassで定義する方が好み。 struct aa { public:        //←下記メンバをクラス外からアクセスするにはpublicで宣言   float x;      //メンバデータ(1)   float y;      //メンバデータ(2) public:   aa(){ x=0.11; y=0.22; }    //←コンストラクタでメンバを初期化                    //※今回は初期化されたのを確かめるため、                    //ここでは 0 でない値を設定しています。   aa& operator=(const aa& rhs)  //演算子(=)のオーバーロード   {     if (this == &rhs) return *this;     x = rhs.x;     y = rhs.y;     return *this;   } }; ================================= 上記の定義を用いて、ご提示のソースを変更したソースを下記に掲載しました。 宜しければ検証してみて下さい。 ※当ソースでは、データ表示の際の行数を少なくするため、配列の要素数を 減らしています。 ※当方では、「Borland C++ 5.5.1」及び、「MinGWのgcc(g++) 3.4.5」で検証 してみました。 ■変更版ソース(下記リンク先参照) http://ideone.com/Zfmpt 以上です。

aneja
質問者

お礼

こんばんは。大変ご丁寧なご回答、どうもありがとうございます。No.1の方へのお礼で書いた operator = の定義が、気持ち悪いなと思っていたのですが、ご教示いただいたようにコンストラクタで初期化すればよいのですね!構造体もこんなことができるとは、ぼんやりと知っていましたが、実際に使ったことはありませんでした。とても勉強になりました。これなら、構造体や入れ子の場合は、fillを使わなくてもいいですね。ご教示いただいた、美しいコードで、もっと勉強します。どうもありがとうございました。

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

わざわざ fill を使わなくても, resize だけで (大きくした部分は) 「デフォルトの初期化」をしてくれるんじゃなかったっけ....

aneja
質問者

お礼

お礼が大変遅くなり、申し訳ありませんでした。ご回答どうもありがとうございます。 ご回答の内容は、初めて知りました。ソースを見ると、デフォルトコンストラクタがあることが要求されているようです…。参考になりました。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.4

一言で言うと現状のgetMでは「右辺が数値型の演算子=を許す型によるdeque/list/vector、もしくはその派生クラス」以外はコンパイルを通せません。 std::fillの第3パラメータ、即ち0x0はどうあがいても数値型でしかないので「要素に数値型を代入可能、もしくは右辺値がintである演算子=を定義済」でなければならないためです。 #3でも言われてますが、このstd::fillは本当に必要ですか? deque/list/vector以外のSTLがアウトである理由は他のSTLにはresize()がないこと。もっともこちらはvector前提ならそう問題ではないでしょう。

aneja
質問者

お礼

再度のご登場、どうもありがとうございます。fillでなくても少ないステップ数で初期化ができればなんでもよいのですが…。恥ずかしながら、0x0はただの数値であることをあまり認識していませんでした。入れ子無しの基本データ型のvectorなら、いつもfillで初期化していました。(宣言と同時にデータ個数がわかっていれば、vector<int> data(10,0); などとしています) まだ、vector以外のコンテナはあまり使った経験がないのですが、resize()が使えないものもあることは、勉強になります。今回に限れば、vector専用関数なので、問題はないかと思います。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

単に 0x0 と書けば, それは当然 int です. だから > fill( vDat.begin(), vDat.end(), 0x0 ); > の「0x0」がint扱いされている のはあたりまえ. でどうすればいいかだけど, それはあなたがここで何をしたいかによる. そもそも fill しないとダメなの?

aneja
質問者

お礼

再度のご登場、どうもありがとうございます。なかなか身につかず、0x0がintだということをうっかり忘れていました。fillの目的は初期化です。今回、vector用のメモリ確保関数を作ったのも、要素が数万~数十万ものvectorデータが多用されているからです。ほとんどのvectorデータは入れ子無しの基本データ型なので、メモリ確保→初期化を一連の動作でやっていました。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

std::fill()があるという事はalgorithmもインクルードしてるはずですが、それはさておき。 std::vector<std::vector<int>> a; という型のオブジェクトaを考えた時に、さてa[0]の型は何でしょうか? そこに整数型は代入できますか? という事です。

aneja
質問者

お礼

ご回答、ありがとうございます。ご指摘通り、algorithmもインクルードしていました。投稿の際に、はしょりすぎました。すみません。 ご回答の意味するところをしばらく考えないと理解できない低レベルですが、入れ子vectorに代入する初期値は、例だとstd::vector<int>型の何かでないといけないのですね。 具体的には、どうするんでしょう?困りました!! でも、入れ子vectorって、一番内側(ここではvector<int>)だけ初期化すればいいような気がしてきました。外側は要素数だけ指定してやれるけど、実体(内側)はまだないんですもんね。私の考え、間違ってましたら、すみませんがご指摘お願いします。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

理由はちゃんとエラーメッセージに書いてありますが....

aneja
質問者

お礼

ご回答、どうもありがとうございます。 >> 理由はちゃんとエラーメッセージに書いてありますが.... はい、おっしゃる通りです…(^_^; 'aa::operator =(const int)' に一致するものが見つからない(関数 fill<aa *,int>(aa *,aa *,const int &) ) 'vector<aa,allocator<aa>>::operator =(const int)' に一致するものが見つからない(関数 fill<vector<aa,allocator<aa> > *,int>(vector<aa,allocator<aa> > *,vector<aa,allocator<aa> > *,const int &) ) よくよく考えてみると、 fill( vDat.begin(), vDat.end(), 0x0 ); の「0x0」がint扱いされているってことなんでしょうか。 とすると、構造体のoperator()オーバーロードは、以下のような感じでよろしいんでしょうか? aa& operator = (const int& rhs) { x = rhs; y = rhs; return *this; }; 引数型と戻り値型が違うのがなんだか気持ち悪いです。 vector<aa,allocator<aa>>::operator =(const int) の方は、どう書けばよいか、サッパリわかりません…。aaの定義中には書けなさそうなのですが??