回答編集履歴

5

refinement

2018/10/13 16:10

投稿

yohhoy
yohhoy

スコア6191

test CHANGED
@@ -28,11 +28,11 @@
28
28
 
29
29
 
30
30
 
31
- 戻り値型`auto&`の場合、`const int&`型の式からは`const int&`が推論され、`int&`型の式からは`int&`が推論されます。`auto&`をテンプレートパラメータ`T&`と読み替えた場合、`T==int`に推論されています。
31
+ 戻り値型`auto&`の場合、`const int&`型の式からは`const int&`が推論され、`int&`型の式からは`int&`が推論されます。`auto&`をテンプレートパラメータ`T&`と読み替えた場合、`T`はそれぞれ`const int`, `int`に推論されています。
32
32
 
33
33
 
34
34
 
35
- 戻り値型`auto&&`の場合、`const int&`型の式からは`const int&`が推論され、`int&`型の式からは`int&`が推論されます。`auto&&`をテンプレートパラメータ`T&&`と読み替えた場合、`T==int&`に推論されています(これがいわゆるForwarding Reference/Universal Referenceです)。ただし`int&`+`&&`はReference Collapsingルールにより`int&`となるため、最終的には前述のように左辺値参照型となります。(`const int&&`,`int&&`のような右辺値参照型には推論されない)
35
+ 戻り値型`auto&&`の場合、`const int&`型の式からは`const int&`が推論され、`int&`型の式からは`int&`が推論されます。`auto&&`をテンプレートパラメータ`T&&`と読み替えた場合、`T`はそれぞれ`const int&`, `int&`に推論されています(これがいわゆるForwarding Reference/Universal Referenceです)。ただし`(const) int&`+`&&`はReference Collapsingルールにより`(const) int&`となるため、最終的には前述のように左辺値参照型となります。(`const int&&`,`int&&`のような右辺値参照型には推論されない)
36
36
 
37
37
 
38
38
 

4

appendix

2018/10/13 16:10

投稿

yohhoy
yohhoy

スコア6191

test CHANGED
@@ -37,3 +37,7 @@
37
37
 
38
38
 
39
39
  戻り値型`decltype(auto)`の場合、戻り値型は`delctype(c[???])`と推論されるルールです。よって`const int&`型の式からは`const int&`が推論され、`int&`型の式からは`int&`が推論されます。
40
+
41
+
42
+
43
+ おまけ:戻り値型`auto`の場合、`const int&`, `int&`型の式いずれからも`int`が推論されます。(トップレベルのcv修飾は引き継がれず、前者も単に`int`となります。)

3

refinement

2018/10/13 15:49

投稿

yohhoy
yohhoy

スコア6191

test CHANGED
@@ -1,4 +1,4 @@
1
- 説明のため、本題に影響しない部分を???で置き換えます。
1
+ 説明のため、本題に影響しない部分を???で置き換えます。また表記簡略化のため以下`std::`も省略します。
2
2
 
3
3
 
4
4
 
@@ -16,7 +16,7 @@
16
16
 
17
17
 
18
18
 
19
- main関数では関数テンプレート`SelectElementry`に左辺値(`a`,`b`)を渡していますから、テンプレートパラメータ`Container`はそれぞれ`const std::vector<int>&`, `std::vector<int>&`に推論されます。return文の式`c[???]`はそれぞれ`std::vector<int>::operator[]() const`, `std::vector<int>::operator[]()`を呼び出します。つまり式`c[???]`の型はそれぞれ`std::vector<int>::const_reference`==`const int&`, `std::vector<int>::reference`==`int&`となっています。
19
+ main関数では関数テンプレート`SelectElementry`に左辺値(`a`,`b`)を渡していますから、テンプレートパラメータ`Container`はそれぞれ`const vector<int>&`, `vector<int>&`に推論されます。return文の式`c[???]`はそれぞれ`vector<int>::operator[]() const`, `vector<int>::operator[]()`を呼び出します。つまり式`c[???]`の型はそれぞれ`vector<int>::const_reference`==`const int&`, `vector<int>::reference`==`int&`となっています。
20
20
 
21
21
 
22
22
 

2

refinement

2018/10/13 15:47

投稿

yohhoy
yohhoy

スコア6191

test CHANGED
@@ -28,12 +28,12 @@
28
28
 
29
29
 
30
30
 
31
- 戻り値型`auto&`の場合、`const int&`からは`const int&`が推論され、`int&`からは`int&`が推論されます。`auto&`をテンプレートパラメータ`T&`と読み替えた場合、`T==int`に推論されています。
31
+ 戻り値型`auto&`の場合、`const int&`型の式からは`const int&`が推論され、`int&`型の式からは`int&`が推論されます。`auto&`をテンプレートパラメータ`T&`と読み替えた場合、`T==int`に推論されています。
32
32
 
33
33
 
34
34
 
35
- 戻り値型`auto&&`の場合、`const int&`からは`const int&`が推論され、`int&`からは`int&`が推論されます。`auto&&`をテンプレートパラメータ`T&&`と読み替えた場合、`T==int&`に推論されています(これがいわゆるForwarding Reference/Universal Referenceです)。ただし`int&`+`&&`はReference Collapsingルールにより`int&`となるため、最終的には前述のように左辺値参照となります。(`const int&&`,`int&&`のような右辺値参照型には推論されない)
35
+ 戻り値型`auto&&`の場合、`const int&`型の式からは`const int&`が推論され、`int&`型の式からは`int&`が推論されます。`auto&&`をテンプレートパラメータ`T&&`と読み替えた場合、`T==int&`に推論されています(これがいわゆるForwarding Reference/Universal Referenceです)。ただし`int&`+`&&`はReference Collapsingルールにより`int&`となるため、最終的には前述のように左辺値参照となります。(`const int&&`,`int&&`のような右辺値参照型には推論されない)
36
36
 
37
37
 
38
38
 
39
- 戻り値型`decltype(auto)`の場合、戻り値型は`delctype(c[???])`と推論されるルールです。よって`const int&`からは`const int&`が推論され、`int&`からは`int&`が推論されます。
39
+ 戻り値型`decltype(auto)`の場合、戻り値型は`delctype(c[???])`と推論されるルールです。よって`const int&`型の式からは`const int&`が推論され、`int&`型の式からは`int&`が推論されます。

1

update

2018/10/13 15:39

投稿

yohhoy
yohhoy

スコア6191

test CHANGED
@@ -1,3 +1,7 @@
1
+ 説明のため、本題に影響しない部分を???で置き換えます。
2
+
3
+
4
+
1
5
  ```C++
2
6
 
3
7
  template<typename Container>