Skip to content

Commit 9b4c3b8

Browse files
committed
functional/function_ref: 詳細説明(#1192)
1 parent d12c259 commit 9b4c3b8

File tree

6 files changed

+402
-8
lines changed

6 files changed

+402
-8
lines changed

reference/functional/function_ref.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace std {
2222
- CV修飾子 *cv* : `const`, CV修飾無し
2323
- noexcept例外指定 *noex* : `true`, `false`
2424
25-
`function_ref`クラステンプレートのあらゆる特殊化は[トリビアルコピー可能](/reference/type_traits/is_trivially_copyable.md)である
25+
`function_ref`クラステンプレートの特殊化は、[`copyable`](/reference/concepts/copyable.md)のモデルである[トリビアルコピー可能](/reference/type_traits/is_trivially_copyable.md)な型となる
2626
2727
2828
### `function`ファミリとの比較
@@ -41,25 +41,25 @@ namespace std {
4141
4242
| 名前 | 説明 | 対応バージョン |
4343
|-----------------|----------------|----------------|
44-
| [`(constructor)`](function_ref/op_constructor.md.nolink) | コンストラクタ | C++26 |
45-
| (destructor) | デストラクタ | C++26 |
46-
| [`operator=`](function_ref/op_assign.md.nolink) | 代入演算子 | C++26 |
47-
| [`operator()`](function_ref/op_call.md.nolink) | 関数呼び出し | C++26 |
44+
| [`(constructor)`](function_ref/op_constructor.md) | コンストラクタ | C++26 |
45+
| `(destructor)` | デストラクタ | C++26 |
46+
| [`operator=`](function_ref/op_assign.md) | 代入演算子 | C++26 |
47+
| [`operator()`](function_ref/op_call.md) | 関数呼び出し | C++26 |
4848
4949
5050
## 推論補助
5151
5252
| 名前 | 説明 | 対応バージョン |
5353
|-----------------|----------------|----------------|
54-
| [`(deduction_guide)`](function_ref/op_deduction_guide.md.nolink) | クラステンプレートの推論補助 | C++26 |
54+
| [`(deduction_guide)`](function_ref/op_deduction_guide.md) | クラステンプレートの推論補助 | C++26 |
5555
5656
5757
## 例
5858
### 例1: 基本の使い方
5959
```cpp example
6060
#include <functional>
6161
#include <iostream>
62-
#include <utility> // nontype
62+
#include <utility>
6363
6464
// 呼び出し可能な何かを受け取る高階関数
6565
int hof(std::function_ref<int(int)> fn)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# operator=
2+
* functional[meta header]
3+
* std[meta namespace]
4+
* function_ref[meta class]
5+
* function[meta id-type]
6+
* cpp26[meta cpp]
7+
8+
```cpp
9+
constexpr function_ref& operator=(const function_ref&) noexcept = default; // (1)
10+
11+
template<class T> function_ref& operator=(T) = delete; // (2)
12+
```
13+
14+
## 概要
15+
コピー代入演算子。
16+
17+
18+
## テンプレートパラメータ制約
19+
- (2) : 以下の制約をみたすとき、代入演算子はdelete宣言される
20+
- `T``function_ref`と同一型ではなく、かつ
21+
- [`is_pointer_v`](/reference/type_traits/is_pointer.md)`<T>``false`であり、かつ
22+
- `T`[`nontype_t`](/reference/utility/nontype_t.md)の特殊化でないこと
23+
24+
25+
## 効果
26+
- (1) : コピー代入。
27+
28+
29+
## 戻り値
30+
`*this`
31+
32+
33+
##
34+
```cpp example
35+
#include <iostream>
36+
#include <functional>
37+
38+
int ident(int x)
39+
{ return x; }
40+
41+
int twice(int x)
42+
{ return x * 2; }
43+
44+
int main()
45+
{
46+
std::function_ref<int(int)> f = ident;
47+
std::function_ref<int(int)> g = twice;
48+
49+
// コピー代入
50+
f = g;
51+
52+
std::cout << f(1) << std::endl;
53+
}
54+
```
55+
56+
### 出力
57+
```
58+
2
59+
```
60+
61+
62+
## バージョン
63+
### 言語
64+
- C++26
65+
66+
### 処理系
67+
- [Clang](/implementation.md#clang): ??
68+
- [GCC](/implementation.md#gcc): ??
69+
- [ICC](/implementation.md#icc): ??
70+
- [Visual C++](/implementation.md#visual_cpp): ??
71+
72+
73+
## 参照
74+
- [P0792R14 `function_ref`: a type-erased callable reference](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0792r14.html)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# operator()
2+
* functional[meta header]
3+
* std[meta namespace]
4+
* function_ref[meta class]
5+
* function[meta id-type]
6+
* cpp26[meta cpp]
7+
8+
```cpp
9+
R operator()(ArgTypes... args) const noexcept(/*noex*/);
10+
```
11+
12+
## 概要
13+
関数を呼び出す。
14+
15+
`operator()`のnoexcept例外指定 *noex* は、[`function_ref`](../function_ref.md)に指定するテンプレートパラメータ`R(ArgTypes...)`部のものと等しい。
16+
17+
18+
## 効果
19+
以下と等価。参照対象に応じた詳細仕様は[コンストラクタ](op_constructor.md)説明を参照のこと。
20+
21+
```cpp
22+
return thunk-ptr(bound-entity, std::forward<ArgTypes>(args)...);
23+
```
24+
* thunk-ptr[italic]
25+
* bound-entity[italic]
26+
* std::forward[link /reference/utility/forward.md]
27+
28+
29+
## 戻り値
30+
`R`型が`void`の場合は何も返さない。そうでなければ、関数呼び出しの戻り値を返す。
31+
32+
33+
##
34+
```cpp example
35+
#include <iostream>
36+
#include <functional>
37+
38+
int ident(int x)
39+
{ return x; }
40+
41+
int main()
42+
{
43+
std::function_ref<int(int)> f = ident;
44+
45+
// 関数呼び出し : 参照しているident()関数を呼び出す
46+
int result = f(1);
47+
48+
std::cout << result << std::endl;
49+
}
50+
```
51+
52+
### 出力
53+
```
54+
1
55+
```
56+
57+
58+
## バージョン
59+
### 言語
60+
- C++26
61+
62+
### 処理系
63+
- [Clang](/implementation.md#clang): ??
64+
- [GCC](/implementation.md#gcc): ??
65+
- [ICC](/implementation.md#icc): ??
66+
- [Visual C++](/implementation.md#visual_cpp): ??
67+
68+
69+
## 参照
70+
- [P0792R14 `function_ref`: a type-erased callable reference](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0792r14.html)
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# コンストラクタ
2+
* functional[meta header]
3+
* std[meta namespace]
4+
* function_ref[meta class]
5+
* function[meta id-type]
6+
* cpp26[meta cpp]
7+
8+
```cpp
9+
template<class F> function_ref(F* f) noexcept; // (1)
10+
11+
template<class F>
12+
constexpr function_ref(F&& f) noexcept; // (2)
13+
14+
template<auto f>
15+
constexpr function_ref(nontype_t<f>) noexcept; // (3)
16+
template<auto f, class U>
17+
constexpr function_ref(nontype_t<f>, U&& obj) noexcept; // (4)
18+
template<auto f, class T>
19+
constexpr function_ref(nontype_t<f>, /*cv*/ T* obj) noexcept; // (5)
20+
21+
constexpr function_ref(const function_ref&) noexcept = default; // (6)
22+
```
23+
* nontype_t[link /reference/utility/nontype_t.md]
24+
25+
## 概要
26+
`function_ref`オブジェクトを構築する。
27+
28+
`function_ref`クラステンプレートパラメータのnoexcept例外指定 *noex* に応じて、説明用の`bool`型テンプレート定数`is-invocable-using<T...>`を次のように定義する :
29+
30+
- *noex* が`true`のとき : [`is_nothrow_invocable_r_v`](/reference/type_traits/is_nothrow_invocable_r.md)`<R, T..., ArgTypes...>`
31+
- *noex* が`false`のとき : [`is_invocable_r_v`](/reference/type_traits/is_invocable_r.md)`<R, T..., ArgTypes...>`
32+
33+
`function_ref`オブジェクトは、説明専用のメンバ変数`thunk-ptr`と`bound-entity`を保持する。
34+
35+
36+
## テンプレートパラメータ制約
37+
- (1) : [`is_function`](/reference/type_traits/is_function.md)`<F>`が`true`、かつ`is-invocable-using<F>`が`true`であること
38+
- (2) : `T`を`remove_refernce_t<F>`としたとき
39+
- `remove_cvref_t<F>`が`function_ref`と同一型ではなく、かつ
40+
- [`is_member_pointer_v`](/reference/type_traits/is_member_pointer.md)`T`が`false`であり、かつ
41+
- `is-invocable-using</*cv*/ T&>`が`true`であること
42+
- (3) : `F`を`decltype(f)`としたとき
43+
- `is-invocable-using<F>`が`true`であること
44+
- (4) : `T`を`remove_refernce_t<F>`、`F`を`F`を`decltype(f)`としたとき
45+
- [`is_rvalue_reference_v](/reference/type_traits/is_rvalue_reference.md)`<U&&>`が`false`であり、かつ
46+
- `is-invocable-using<F, /*cv*/ T&>`が`true`であること
47+
- (5) : `F`を`decltype(f)`としたとき
48+
- `is-invocable-using<F, /*cv*/ T*>`が`true`であること
49+
50+
51+
## 適格要件
52+
- (3), (4), (5) : `F`を`decltype(f)`としたとき、[`is_pointer`](/reference/type_traits/is_pointer.md)`<F> ||` [`is_member_pointer`](/reference/type_traits/is_member_pointer.md)`<F>`が`true`ならば、`f`がヌルポインタでないこと。
53+
54+
55+
## 事前条件
56+
- (1) : `f`がヌルポインタでないこと。
57+
58+
59+
## 効果
60+
- (1) : `bound-entity`を`f`で、`thunk-ptr`を説明専用の関数`thunk`へのアドレスで初期化する。
61+
- [関数呼び出し`thunk(bound-entity, call-args...)`](op_call.md)は[`invoke_r`](/reference/functional/invoke_r.md)`<R>(f, call-args...)`と等価。
62+
- (2) : `bound-entity`を[`addressof`](/reference/memory/addressof.md)`(f)`で、`thunk-ptr`を説明専用の関数`thunk`へのアドレスで初期化する。
63+
- [関数呼び出し`thunk(bound-entity, call-args...)`](op_call.md)は[`invoke_r`](/reference/functional/invoke_r.md)`<R>(static_cast</*cv*/ T&>(f), call-args...)`と等価。
64+
- (3) : `bound-entity`を未規定オブジェクトへのポインタまたはヌルポインタで、`thunk-ptr`を説明専用の関数`thunk`へのアドレスで初期化する。
65+
- [関数呼び出し`thunk(bound-entity, call-args...)`](op_call.md)は[`invoke_r`](/reference/functional/invoke_r.md)`<R>(f, call-args...)`と等価。
66+
- (4) : `bound-entity`を[`addressof`](/reference/memory/addressof.md)`(obj)`で、`thunk-ptr`を説明専用の関数`thunk`へのアドレスで初期化する。
67+
- [関数呼び出し`thunk(bound-entity, call-args...)`](op_call.md)は[`invoke_r`](/reference/functional/invoke_r.md)`<R>(f, static_cast</*cv*/ T&>(obj), call-args...)`と等価。
68+
- (5) : `bound-entity`を`obj`で、`thunk-ptr`を説明専用の関数`thunk`へのアドレスで初期化する。
69+
- [関数呼び出し`thunk(bound-entity, call-args...)`](op_call.md)は[`invoke_r`](/reference/functional/invoke_r.md)`<R>(f, obj, call-args...)`と等価。
70+
- (6) : コピーコンストラクタ。
71+
72+
73+
## 例外
74+
投げない
75+
76+
77+
## 例
78+
```cpp example
79+
#include <functional>
80+
#include <iostream>
81+
#include <utility>
82+
83+
int ident_func(int x)
84+
{ return x; }
85+
86+
struct ident_functor {
87+
int operator()(int x) const
88+
{ return x; }
89+
};
90+
91+
struct X {
92+
int ident_func(int x) const
93+
{ return x; }
94+
};
95+
96+
97+
int main()
98+
{
99+
// (1) 関数ポインタ
100+
{
101+
std::function_ref<int(int)> f1 = &ident_func;
102+
std::cout << "(1) : " << f1(1) << std::endl;
103+
}
104+
// (2) 関数オブジェクト
105+
{
106+
ident_functor functor;
107+
std::function_ref<int(int)> f2 = functor;
108+
std::cout << "(2) : " << f2(2) << std::endl;
109+
}
110+
// (3) メンバ関数
111+
{
112+
std::function_ref<int(X&, int)> f3 = std::nontype<&X::ident>;
113+
X obj;
114+
std::cout << "(3) : " << f3(obj, 3) << std::endl;
115+
}
116+
// (4), (5) メンバ関数+オブジェクト束縛
117+
{
118+
X obj;
119+
std::function_ref<int(int)> f4{std::nontype<&X::ident>, obj};
120+
std::cout << "(4) : " << f4(4) << std::endl;
121+
std::function_ref<int(int)> f5{std::nontype<&X::ident>, &obj};
122+
std::cout << "(5) : " << f5(5) << std::endl;
123+
}
124+
// (6) コピーコンストラクタ
125+
{
126+
std::function_ref<int(int)> f1 = &ident_func;
127+
std::function_ref<int(int)> f6 = f1;
128+
std::cout << "(6) : " << f6(6) << std::endl;
129+
}
130+
}
131+
```
132+
* std::nontype[link /reference/utility/nontype_t.md]
133+
134+
### 出力
135+
```
136+
(1) : 1
137+
(2) : 2
138+
(3) : 3
139+
(4) : 4
140+
(5) : 5
141+
(6) : 6
142+
```
143+
144+
145+
## バージョン
146+
### 言語
147+
- C++26
148+
149+
### 処理系
150+
- [Clang](/implementation.md#clang): ??
151+
- [GCC](/implementation.md#gcc): ??
152+
- [ICC](/implementation.md#icc): ??
153+
- [Visual C++](/implementation.md#visual_cpp): ??
154+
155+
156+
## 参照
157+
- [P0792R14 `function_ref`: a type-erased callable reference](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0792r14.html)

0 commit comments

Comments
 (0)