• 締切済み

std::listの代入について

最近std::listを勉強し始めたのですが質問があります。 あるクラスに以下を用意しました。 メンバ変数 std::list< int > list_int; メンバ関数 void SetListInt( const std::list< int > *temp_list ){ list_int = *temp_list; } 以下質問内容です。 ・この SetListInt 関数の場合 temp_list の先頭のみが代入されますか? ・また, temp_list の元の場所が削除または変更されても list_int の中身(この場合は先頭のみ?)は変わらないですよね? ・引数で貰って中身を全部代入したいならイテレータでfor文を回すしかないのでしょうか? 質問が多く拙文でお恥ずかしいのですが、よろしければご回答お願い致します。

みんなの回答

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

「大きなデータのやりとりはポインタ(又は参照)でした方が良い」ってのはその通り. ただ, 「配列は膨大な量になるからポインタで渡せ」 だと「配列」に限定しちゃってる. そうすると, 今の例のように「配列がどこにも出てこない」状況で言われても「何を言ってるんだ」ということになる. そもそも C++ において配列をポインタ以外でどう渡すのかってところから疑問だったりするわけだが. あと, #2 は SetListInt のなかで list_int = *temp_list; としているところを「全部の要素がコピー」と言ってるんだと思う. 実際, ここは全部コピーしちゃってるよね. 以下個人的な意見だけど, const でもらうなら nullptr を使いたいとかの特殊な事情がない限りポインタより参照の方が自然じゃないかなぁ.

yaochan
質問者

補足

私用で度々遅れてしまいすいません。 配列という表現に関しては齟齬が生まれてしまい申し訳ないです。 あ、なるほどです。 たしかに代入するとデータの移動と同じ事になってしまいますよね... しかし、ポインタ元の情報が意図しない書き換えがないとは保証がなく、クラスが独立して値を持ちたいとなると代入するしかないですよね?

回答No.4

> 配列は膨大な量になるからポインタで渡せとお聞きしたのですが list<T> は配列じゃないよ。

yaochan
質問者

補足

listやvector等は配列とは全く違うものなんですね。言い表せられる言葉が配列と思い浮かんだので使用しました。失礼しました。

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

? 「配列は膨大な量になるからポインタで渡せ」であなたが何を言いたいのか, さっぱりわからない. どこにそんなことが書いてあったのかもわからんし, そもそも今の文脈ではどこにも「配列」が出てきていないんだけど. この形では参照にしとけばいいようにしか思えない.

yaochan
質問者

補足

大きなデータのやりとりはポインタ(又は参照)でした方が良いと思うのですが間違っていますか? listやvector等は配列とは全く違うものなんですね。言い表せられる言葉が配列と思い浮かんだので使用しました。失礼しました。 ポインタですとポインタで渡してるのが視覚的に分かる為好んで使っています。ので可能ならばポインタでやりたいのです。

回答No.2

とりあえず、 void SetListInt( const std::list< int > *temp_list ){ list_int = *temp_list; } と void SetListInt( const std::list< int > temp_list ){ list_int = temp_list; } で、同じ事が起こりますから、「全部の要素がコピー」されます。 なので、 > 配列は膨大な量になるからポインタで渡せとお聞きしたのですが ということを聞きかじったにしては、「ポインタで渡ってない」ので、膨大な量のコピーが発生します。 ※もっとも、気にするほどの「膨大な量」かどうかは疑問ですが。 あと、配列と、list を含む、(STLのような)コンテナクラスというのは、別物です。 配列のように、「ほとんどあらゆるところで、配列名は配列の先頭アドレスに読み替えられる」ということはなく、ちゃんと、ひとまとまりの「コンテナ」として機能します。 なので、*temp_list という「リストの中身」は、「リストの中身丸ごと」です。

yaochan
質問者

補足

返事が遅れてしまい申し訳ありません。 配列と違って先頭だけでは無く中身をそのまま代入できるのですね。 要素数の違うlist同士を代入しても全く同じものになると考えてもよろしいですか? これはポインタで渡っていないのですか? ポインタ自体まだ理解し得てないところが多いです...

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

そもそもなんでポインタで渡しているのかがよくわからんが.... とりあえず, 仕様を読んでください.

yaochan
質問者

補足

引数ですか? 配列は膨大な量になるからポインタで渡せとお聞きしたのですが

関連するQ&A

  • std::mapのメモリアロケータについて

    こんにちは。 質問させてください。 現在VisualStudio2008 Academic EditionでC++のプログラムを書いています。 vectorで使用可能なアロケータを作ったのですが、mapでそのアロケータを利用する方法がわかりません。 // vectorで自作アロケータを利用 std::vector< char, my_allocator<char> > myVec; // mapで自作アロケータを利用 std::map< int, float, std::less< int >, my_allocator< std::pair< int, float > > > myMap; vectorの場合はコンパイルできるのですがmapの場合は error C2664: 'my_allocator<_type>::allocator(const my_allocator<_type> &)' : 1 番目の引数を 'my_allocator<_type>' から 'const my_allocator<_type> &' に変換できません。 というエラーが出てコンパイルできません。 ご教授願います。

  • pythonのリスト代入が分かりません。

    pythonの独学をしていまして、 参考書の練習問題を解こうとした際に、 下記のようにプログラムを書いた際に、Temp_new=Temp とリストにリストを代入させた後に、片方だけリストの一部を変更させた際に、両方ともに変更が適応されてしまい、なぜそうなるの分かりません。どなたかどうしてこうなるのかご存じでしょうか? temp=[] temp_new=[] d_time=[8,9,10] cnt=0 for n in d_time: d_add=int(input('Please type temparation data >>')) temp.append(d_add) print('{} o\'clock temparation is {}'.format(d_time[cnt],d_add)) cnt+=1 temp_new=temp temp_new[1]='N/A' print('temp={}'.format(temp)) print('temp_new={}'.format(temp_new)) ※添付ファイルの黄色部分を変えた気が無いのですが、 なぜか変わってしまいます。

  • 警告「代入される前に使われている」を出す方法

    bccで以下のコードをコンパイルすると。 「'i' は、おそらく値が代入される前に使われている」 と警告が出ますが、 「'h' は、おそらく値が代入される前に使われている」 とは警告を出してくれません。 警告を出す方法ってないでしょうか? Hogeメンバに bool 型の初期化フラグでも実装しようかな・・・。 #include <iostream> class Hoge { public: Hoge(){ } Hoge( int i ){ t = i; } operator int(){ return t; } int t; }; int main() { int i; Hoge h; std::cout << i << std::endl; std::cout << h << std::endl; return 0; }

  • 関数に値の代入 [C言語]

    C言語初心者です。関数とポインタについて勉強していたのですが、ふと関数の型を知りたくなってVC++で型を調べてみたんです。そしたら、void型で引数のない関数の型は void (__cdecl*)() となっていました。voidと__cdeclはわかります。 そしてこれ型に*が入ってるじゃないですか。ということは関数はポインタということになると思います。なので私はもしかしたら値の代入ができるのではないか、と思ったのです。早速、 f1=f2;(f1とf2は型と内容の同じ関数) や、 (*f1)=(*f2); としてポインタの中身や参照先の関数の実態の値を処理中に書き換えてみようとしました。ですが、多分そうなるとは思ったのですが、コンパイルエラーが出ました。 《エラーの内容》 error C2106:'=':左のオペランドが、左辺値になっていません。 warning C4550:式は引数リストのない関数として評価します。 関数を書き換えようとすること自体馬鹿げていることは重々承知です。でも、微かにいけそうな気がするんですよ。代入させたくないなら関数の型は一律constにすると思うし(実際関数をconstをつけて宣言してもOKだった、(プロトタイプ有り無しでも))、関数への代入は問答無用で駄目なのならばそういうエラーメッセージを出すと思うんです。 関数の書き換えは100%無理でしょうか?それとも関数を書き換える方法があるでしょうか?回答よろしくお願いします。

  • C++ iteator const を使ったプログラムがコンパイルできない

    以下のプログラムがコンパイルできません。 理由もよく分かりません。 ----------------- #include <algorithm> #include <list> struct Hoge { std::list<Hoge*> l; Hoge * f() const { std::list<Hoge*>::iterator i = l.begin(); return 0; } }; -------------------- g++ 4.1.1 を使っていますが % g++ -c test1.cc test1.cc: In member function 'Hoge* Hoge::f() const': test1.cc:8: error: conversion from 'std::_List_const_iterator<Hoge*>' to non-scalar type 'std::_List_iterator<Hoge*>' requested となります。 l.begin() が const で代入できないということだと思うのですが std::list<Hoge*> l; の部分には const を使っていませんし良く分かりません。 また、 Hoge * eval() const { の const を消すか、 std::list<Hoge*>::iterator i = l.begin(); の代入をやめると コンパイルが通ります。 const は return するポインタの先の領域を変更不可にしている と解釈しているのですが、戻り値と関係ない代入がどうして影響を受けるのかが謎です。 (実際は、もう少し違う大きいプログラムですが関係なさそうな部分を削って 上でも同様のエラーメッセージが出ることを確認しました。)

  • リスト構造の設定のしかた

    メンバ変数が配列のlist_before構造体に設定してあるものを、リスト構造のlist_after構造体に設定し直したいです。 どのように設定すればいいのでしょうか? また、list_before構造体とlist_after構造体を引数にした関数で設定したいのですが呼び出し元と先の引数はどう書けばいいのでしょうか? その際の構造体とメンバ変数は以下になります。 ご教授どうぞ宜しくお願いいたします。 struct list_before { char *name[5]; int size[5]; }; struct list_after { char *name; int size; struct list *next; };

  • C++ vectorのbeginについて

    VC++2010にて下記コードのビルドは通るのですが、 vVecotrInt, vVectorIntPtrの要素数0のとき、iptr代入時に Debug assertaion Failed! vector iterator not dereferencableとなります。 そもそもbegin()はイテレータなので、ポインタに代入しようとしていることが間違いかと思うのですが。 質問1.int* iptr = ~ ではなく、std:vector<int>::iteratorとすれば、     要素数が0でもエラーがおきません。この違いは何でしょうか? 質問2.そもそもイテレータをポインタに代入して何か得することがあるんでしょうか?     ただイテレータとポインタは同じようなものだと思って、コーディングしてるだけなんでしょうか・・・ コード: // vVectorIntの要素を間接参照して(参照先はint)、そのアドレスをポインタに格納 std::vector<int> vVectorInt; int* iptr = &*vVectorInt.begin(); // ここでvector iterator not dereferencable // vVectorIntPtrの要素を間接参照して(参照先はint*)、ポインタに格納 std::vector<int*> vVectorIntPtr; int* iptr = *vVectorIntPtr.begin(); // ここでvector iterator not dereferencable // vVecotrIntPtr2の要素数0のときでも、イテレータを使えば問題ない std::vector<int*> vVectorIntPtr2; std::vector<int*>::iterator itr = vVectorIntPtr2.begin();

  • std::wstringの継承

    #include<iostream> #include<string> #include <stdlib.h> #include <locale.h> #include <boost/lexical_cast.hpp> using boost::lexical_cast; using namespace std; VisualC++2008ExpressEditionで文字や数字を簡単に扱えるクラスを今作ろうとしていて以下のように作ってみました。 class multiString:public std::wstring{ public:   multiString(const wchar_t *ws){     /* multiString class自体に代入 */   } }; しかし、このwchar_tをクラスに代入する処理として、 multiString(const wchar_t *s)std::wstring(s); とすると、「error C2082: 仮パラメータ 's' が再定義されました。」となりますし、 multiString(const wchar_t *s)*this=s; とすると、例外が発生してしまします。 wstringだったら、簡単に代入処理として出来るのですが、継承した場合はどの様に実装すればいいのでしょうか? 宜しくお願いします。

  • std::cout << p と std::cout << *p の違

    std::cout << p と std::cout << *p の違いは? VC++でコードを書きながらC++を学んでいます。 ポインタで疑問に思ったことがあるので質問させて下さい。 int* p; int n = 100; p = &a; 上記のように変数を宣言・代入した場合、 std::cout << p と std::cout << *p のどちらでも"100"と表示されます。 これら二つの違いは何でしょうか? 本来*pとすべきところをpにしてもVC++が気を利かせて &pのアドレスに入っているデータを表示してくれているということでしょうか?

  • キャストの仕方(std::stringをconst char*へ)を教えてください。

    c++で作成したものをコンパイルしたところ、 下記のようなエラーメッセージが表示されました。 cannot convert ‘std::string’ to ‘const char*’ for argument ‘1’ to ‘int stat(const char*, stat*) 自分の解釈では、 stat関数の第1引数がconst char*なのに、 プログラムの中では  #include <sys/types.h>  #include <sys/stat.h>  using namespace std;   :  string aaa;   :  struct stat st;  if(stat(aaa,&st)!=-1){・・・   : という感じで記述しているので、 型が変換できない という感じのことを言っているのかなぁ・・・? と思っているのですが、間違いですか? また、間違えていないとしたら・・・、 このstringで宣言しているaaaをchar*(?)にキャストする方法 と言いますか、このエラーを解決する方法を教えてください。 毎度のことですが、理解不十分で、質問の意味が通じにくいかも しれませんが、どうか宜しくお願いいたします。m(_ _)m

専門家に質問してみよう