構造体を要素に持つvectorにpushbackで構造体の要素を入力するとき構造体名()を引数にして何故できるのかがわかりません

[戻る]
NI 2010/08/18(水) 23:40:25
VC++2008です。

class AnimDraw{
    struct animpat{                
        vector<int> ghlist;
        int anigap;
        animpat(){ anigap=1; }//animpatのコンストラクタ(構造体のコ
ンストラクタを宣言可能)
    };
    vector<animpat> aplist;
public:
    //コンストラクタ(一つ目のanimpatをセット?。)
    AnimDraw(){    
        aplist.push_back( animpat() );
    }
};

このソースでわからない事があります。下から3行目の
aplist.push_back( animpat() );
で、animpat()を引数にして、構造体animpatを要素に持つvectorにanimpatの要素を入力
しているようなのですが、
構造体名() を引数にして入力できるという記述が参考書やネットで見かける事ができ
ないために自分の考えに自信がもてないでいます。
構造体名() をpush_backの引数にしてvectorの要素に入力できるという記述がされてい
る参考書やネットがありましたらご教示願います。

Ban 2010/08/19(木) 00:34:51
言語仕様としてはISO/IEC:14882の12.2 Temporary Objectsあたりに書いてあります。
(日本語訳のJIS X3014ならhttp://www.jisc.go.jp/index.htmlから閲覧できます)

元ソースの場合、動作的にはこう(↓)書いてるのとほぼ一緒です。
 {
  animpat temp;
  aplist.push_back(temp);
 }

tempとかをわざわざ作らずに直接temporary object(関数の引数として生成され
関数が終わると破棄される名も亡き変数)を作っています。
なお、push_backは渡された引数のコピーを保持するので、
コピー後にコピー元がどうなろうと頓着しません。


ちなみに、void foo(int bar) {} に対して、
foo(int()); とかも書けたりします。

NI 2010/08/19(木) 01:23:55
[[解決]]
おかげで自信がもてました。
1〜2行目は参考にさせていただきます。
3〜7行目がわかりやすかったです。
コンストラクタとテンポラリオブジェクトをキーワードにして検索してみると何か
それらしいのもヒットするようになってきました。
私の持ってる本は初心者用だからなのかテンポラリオブジェクトの記述が見つからず、
この言葉の存在を教えていただいた効果が大きいです。
感謝します。どうも有難うございました。

仲澤@失業者 2010/08/19(木) 12:00:59
解決しちゃってますが、重箱の隅的補足をさせてもらうと。
--
  aplist.push_back(animpat);
は、
  1.animpat::animpat()がスタック上で実行され
  2.vector<animpat>::push_back()がコールされる
--
  animpat temp;
  aplist.push_back(temp);
の方は
  1.animpat::animpat()がスタック上で実行され(tempの方)
  2.さらにコピーコンストラクタ、おそらく
    animpat::animpat( const animpat&)が
    スタック上で実行され(引数となった方)
  3.vector<animpat>::push_back()がコールされる

実際にスタックが利用されるかどうかは処理系によると思いますけど(vv;)。
引数にCStringを渡せと書いてある無邪気なソースを見るたびにため息が
でますけど、なるべくやめましょう。
void foo( CString str) ; // こういうのはやめましょう。

YuO [E-Mail] 2010/08/19(木) 12:21:08
>   2.さらにコピーコンストラクタ、おそらく
>     animpat::animpat( const animpat&)が
>     スタック上で実行され(引数となった方)

std::vector<T, A>::push_backの引数はconst T &ですから,
push_backの呼び出し前にコピーコンストラクタは呼び出されません。
ただし,push_backの中で呼び出されるとは思います。

仲澤@失業者 2010/08/19(木) 12:45:40
>std::vector<T, A>::push_backの引数はconst T &ですから,
おおっ、そうでした。ごめんなさい。

επιστημη [E-Mail] [HomePage] 2010/08/19(木) 22:42:32
> ただし,push_backの中で呼び出されるとは思います。

さらに重箱の隅の隅をほじくれば、C++0Xでは
vector<T>::emplace_back(T&&) が追加されてて、
こいつ使えばコピーコンストラクトすら起こらないとゆー。

古いスレッドには追加発言できません。