teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

4

微修正

2018/03/06 09:12

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -67,7 +67,7 @@
67
67
  }
68
68
  ```
69
69
  のpush_back呼び出しで、"abcdefghijklmnopqrstuvwxyz"によりstd::string型の一時オブジェクトが生成されてpush_back()関数に渡されます。
70
- C++11以降のpush_back()は右辺値を受け取るとムーブしますので、コピーを最小限にしてくれます。(C++11ではemplace_backを使う一般的です。yohhoyさんご指摘の通り、この例示にはemplace_backでは適切な説明にならないのでpush_backに変更しました。)
70
+ C++11以降のpush_back()は右辺値を受け取るとムーブしますので、コピーを最小限にしてくれます。(C++11ではemplace_backを使うこと多いです。しかし、yohhoyさんご指摘の通り、この例示にはemplace_backでは適切な説明にならないのでpush_backに変更しました。)
71
71
 
72
72
  しかし、右辺値参照がなかった場合、ムーブで受け取るためには専用の関数を用意する必要があります。
73
73
 

3

微修正

2018/03/06 09:12

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -67,7 +67,7 @@
67
67
  }
68
68
  ```
69
69
  のpush_back呼び出しで、"abcdefghijklmnopqrstuvwxyz"によりstd::string型の一時オブジェクトが生成されてpush_back()関数に渡されます。
70
- push_back()は右辺値を受け取るとムーブしますので、コピーを最小限にしてくれます。(C++11ではemplace_backを使うのが一般的です。yohhoyさんご指摘の通り、この例示にはemplace_backでは適切な説明にならないのでpush_backに変更しました。)
70
+ C++11以降のpush_back()は右辺値を受け取るとムーブしますので、コピーを最小限にしてくれます。(C++11ではemplace_backを使うのが一般的です。yohhoyさんご指摘の通り、この例示にはemplace_backでは適切な説明にならないのでpush_backに変更しました。)
71
71
 
72
72
  しかし、右辺値参照がなかった場合、ムーブで受け取るためには専用の関数を用意する必要があります。
73
73
 

2

ミス修正

2018/03/06 09:08

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -59,27 +59,27 @@
59
59
  int main()
60
60
  {
61
61
  std::vector<std::string> aList;
62
- aList.emplace_back("abcdefghijklmnopqrstuvwxyz");
62
+ aList.push_back("abcdefghijklmnopqrstuvwxyz");
63
63
  for (auto& str : aList)
64
64
  {
65
65
  std::cout << str << "\n";
66
66
  }
67
67
  }
68
68
  ```
69
- emplace_back呼び出しで、"abcdefghijklmnopqrstuvwxyz"によりstd::string型の一時オブジェクトが生成されてemplace_back()関数に渡されます。
69
+ push_back呼び出しで、"abcdefghijklmnopqrstuvwxyz"によりstd::string型の一時オブジェクトが生成されてpush_back()関数に渡されます。
70
- emplace_back()は右辺値を受け取るとムーブしますので、コピーを最小限にしてくれます。(実際には、このケースでは「コピー省略」機能るかもしれませ文法上ムーブ。)
70
+ push_back()は右辺値を受け取るとムーブしますので、コピーを最小限にしてくれます。(C++11ではemplace_backを使うのが一般的で。yohhoyさご指摘の通りこの例示にemplace_backは適切な説明にならないのでpush_backに変更しました。)
71
71
 
72
72
  しかし、右辺値参照がなかった場合、ムーブで受け取るためには専用の関数を用意する必要があります。
73
73
 
74
74
  ```C++
75
- void emplace_back_move(T& rhs);
75
+ void push_back_move(T& rhs);
76
76
  ```
77
77
  みたいな感じです。しかし、左辺値参照は一時オブジェクト(右辺値)を受け取れません。なので、次のように呼び出す必要があります。
78
78
 
79
79
  ```C++
80
80
  {
81
81
  std::string str("abcdefghijklmnopqrstuvwxyz");
82
- aList.emplace_back_move(str);
82
+ aList.push_back_move(str);
83
83
  }
84
84
  ```
85
85
 

1

あまり適切でない説明だったので一部削除

2018/03/06 09:04

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -83,38 +83,8 @@
83
83
  }
84
84
  ```
85
85
 
86
- これだけでもなかなか嫌なものです。(なお、VC++は「独自拡張」と称してクラス型については左辺値参照で右辺値を受け取ることができます。)
86
+ なかなか嫌なものです。(なお、VC++は「独自拡張」と称してクラス型については左辺値参照で右辺値を受け取ることができます。)
87
87
 
88
- 更に、同じ文字列を複数pushしたい時は、次のような関数を用意します。
89
-
90
- ```C++
91
- void emplace_back(T const& rhs);
92
- ```
93
-
94
- そして、ヒープ獲得を最小限にするためには、続けて次のように呼び出します。(const参照は左辺値、右辺値共に受け取れます。)
95
-
96
- ```C++
97
- {
98
- std::string str("abcdefghijklmnopqrstuvwxyz");
99
- aList.emplace_back_move(str);
100
- }
101
- {
102
- std::string str("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
103
- aList.emplace_back(str);
104
- aList.emplace_back(str);
105
- aList.emplace_back_move(str);
106
- }
107
- ```
108
-
109
- 右辺値参照のお陰で次のように書いても、重たいヒープ獲得が無駄に発生しないってありがたいものです。
110
-
111
- ```C++
112
- aList.emplace_back("abcdefghijklmnopqrstuvwxyz");
113
- aList.emplace_back("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
114
- aList.emplace_back("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
115
- aList.emplace_back("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
116
- ```
117
-
118
88
  下記が参考になると思います。
119
89
  [rvalue reference 完全解説](https://cpplover.blogspot.jp/2009/11/rvalue-reference_23.html)
120
90
  [第35回目 ムーブと右辺値参照と特殊メンバ関数と](https://theolizer.com/cpp-school1/cpp-school1-35/)