Skip to content

Commit f23fbb8

Browse files
改行をLFに統一
1 parent cae6a31 commit f23fbb8

16 files changed

+1697
-1697
lines changed

article/lib/dont_use_noexcept.md

+25-25
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
# 標準ライブラリにおける、関数にnoexceptを付けない条件
2-
3-
C++11から、`throw`キーワードを使用した関数の例外指示が非推奨になり、例外を投げないことを明示する`noexcept`キーワードが追加された。
4-
5-
標準ライブラリも`noexcept`に対応しているが、仕様上、自然言語で「Throws: Nothing.(例外を投げない)」と書いてあって、`noexcept`が付いていないものがいくつか存在する。
6-
7-
8-
たとえば、[`std::mutex`](/reference/mutex/mutex.md)クラスの[`unlock()`](/reference/mutex/mutex/unlock.md)メンバ関数には、`noexcept`が付いていない。
9-
10-
これについては、「[N3279 - Conservative use of noexcept in the library](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3279.pdf)」のペーパーで論じられている。簡単に言えば、`noexcept`を付けない条件は以下のようになる:
11-
12-
13-
関数に事前条件が設定されている場合(`unlock()`の場合は、すでにアンロックされていないこと)、事前条件の不一致を報告するために、実装が例外を投げる場合がある。そういう関数に対しては、`noexcept`は付いていない。
14-
15-
16-
例外があることを前提としていない、C言語の互換ライブラリには、`noexcept`が付いている場合がある。たとえば、[`atomic_exchange()`](/reference/atomic/atomic_exchange.md)のような、[アトミックライブラリ](/reference/atomic.md)の関数などには、`noexcept`が付いている。
17-
18-
19-
## 関連項目
20-
- [C++11 noexcept](/lang/cpp11/noexcept.md)
21-
22-
23-
## 参照元
24-
この記事は、「[標準ライブラリにおける、関数にnoexceptを付けない条件 - Faith and Brave - C++で遊ぼう](http://d.hatena.ne.jp/faith_and_brave/20130620/1371715296)」のブログエントリから転載し、修正を行っている。
25-
1+
# 標準ライブラリにおける、関数にnoexceptを付けない条件
2+
3+
C++11から、`throw`キーワードを使用した関数の例外指示が非推奨になり、例外を投げないことを明示する`noexcept`キーワードが追加された。
4+
5+
標準ライブラリも`noexcept`に対応しているが、仕様上、自然言語で「Throws: Nothing.(例外を投げない)」と書いてあって、`noexcept`が付いていないものがいくつか存在する。
6+
7+
8+
たとえば、[`std::mutex`](/reference/mutex/mutex.md)クラスの[`unlock()`](/reference/mutex/mutex/unlock.md)メンバ関数には、`noexcept`が付いていない。
9+
10+
これについては、「[N3279 - Conservative use of noexcept in the library](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3279.pdf)」のペーパーで論じられている。簡単に言えば、`noexcept`を付けない条件は以下のようになる:
11+
12+
13+
関数に事前条件が設定されている場合(`unlock()`の場合は、すでにアンロックされていないこと)、事前条件の不一致を報告するために、実装が例外を投げる場合がある。そういう関数に対しては、`noexcept`は付いていない。
14+
15+
16+
例外があることを前提としていない、C言語の互換ライブラリには、`noexcept`が付いている場合がある。たとえば、[`atomic_exchange()`](/reference/atomic/atomic_exchange.md)のような、[アトミックライブラリ](/reference/atomic.md)の関数などには、`noexcept`が付いている。
17+
18+
19+
## 関連項目
20+
- [C++11 noexcept](/lang/cpp11/noexcept.md)
21+
22+
23+
## 参照元
24+
この記事は、「[標準ライブラリにおける、関数にnoexceptを付けない条件 - Faith and Brave - C++で遊ぼう](http://d.hatena.ne.jp/faith_and_brave/20130620/1371715296)」のブログエントリから転載し、修正を行っている。
25+
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,117 @@
1-
# 全ての非型テンプレート引数の定数式評価を許可
2-
3-
* cpp17[meta cpp]
4-
5-
## 概要
6-
C++17では、非型テンプレート引数(non-type template argument)で扱える型はとくに変わらないが、渡せる値についての制限緩和が行われる。
7-
8-
今回緩和されるのは、ポインタの値である。C++14までは、以下のような制限があった:
9-
10-
- 静的記憶域を持つ完全オブジェクトへのポインタ値もしくは参照、もしくは
11-
- ヌルポインタ値に評価される定数式、
12-
- ヌルメンバポインタ値に評価される定数式であること
13-
14-
つまり、`static`でないオブジェクトへのポインタは、ヌルポインタしか渡せなかった。
15-
16-
C++17ではこの制限が撤廃され、定数式で評価されるポインタならなんでも渡せるようになる。その許可される定数式での評価には、配列からポインタへの変換や、関数から関数ポインタへの変換、修飾の変換なども含まれる。
17-
18-
## 仕様
19-
直接の根拠は、次の記述が与えている。C++14での記述は削除され、C++17で置き換えられた。
20-
21-
[n4659](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf) [temp.arg.nontype]/2より
22-
23-
型ではないテンプレートパラメータのテンプレート引数は、テンプレートパラメータの型の変換された定数式になる。
24-
参照型またはポインタ型の非型テンプレートパラメータの場合、定数式の値は参照してはいけない(ポインタ型の場合は、次のアドレスにはならない)
25-
26-
- サブオブジェクト
27-
- 一時オブジェクト
28-
- 文字列リテラル
29-
- typeid式の結果
30-
- 定義済みの`__func__`変数
31-
32-
C++14からC++17にかけて、次の表のような変更があったと考えられる。[n4198](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4198.html)を参照。
33-
34-
| パラメータ種別 | C++14での引数の構文 |
35-
|---|---|
36-
| 整数または列挙 | 任意の定数式 |
37-
| ポインタ型 | 正確な構文と実体、配列、関数、リンケージを使用して静的記憶期間オブジェクトまたは関数を参照する。NULLポインタに評価される任意の定数式 |
38-
| 参照型 | 正確な構文とオブジェクト、関数、リンケージを使用して静的記憶期間オブジェクトまたは関数を参照する |
39-
| メンバーへのポインタ | 正確な構文と`&X::y` 、またはメンバーへのポインターが`NULL`に評価される任意の定数式 |
40-
| [`std::nullptr_t`](/reference/cstddef/nullptr_t.md) | 任意の定数式 |
41-
42-
から
43-
44-
| パラメータ種別 | C++17での引数の構文 |
45-
|---|---|
46-
| 整数または列挙 | 任意の定数式 |
47-
| ポインタ型 | 静的記憶期間を持つ、関数、または`NULL`ポインターを持つ完全なオブジェクトのアドレスに評価される任意の定数式 |
48-
| 参照型 | 静的記憶期間を持つ完全なオブジェクトまたは関数を参照する、`glvalue`に評価される任意の定数式。 |
49-
| メンバーへのポインタ | 任意の定数式 |
50-
| [`std::nullptr_t`](/reference/cstddef/nullptr_t.md) | 任意の定数式 |
51-
52-
##
53-
C++14では、以下のコードはコンパイルエラーとなるが、C++17では問題なくコンパイルされる。
54-
55-
```cpp example
56-
template<int* p>
57-
struct A {};
58-
59-
int n;
60-
A<&n> a; // ok
61-
62-
constexpr int* p() { return &n; }
63-
A<p()> b; // error in C++14
64-
65-
constexpr int* q() { return nullptr; }
66-
A<q()> c; // ok!
67-
68-
int main(){}
69-
```
70-
71-
### 出力例
72-
clang での出力例
73-
74-
C++14
75-
76-
```
77-
prog.cc:8:3: error: non-type template argument does not refer to any declaration
78-
A<p()> b; // error in C++14
79-
^~~
80-
prog.cc:1:15: note: template parameter is declared here
81-
template<int *p>
82-
^
83-
1 error generated.
84-
```
85-
86-
C++17
87-
88-
```
89-
```
90-
91-
## この機能が必要になった背景・経緯
92-
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4198.html を google 翻訳して編集
93-
94-
ポインター、参照、およびメンバーへのポインターに対する構文上の制限はぎこちなく、妥当なリファクタリングを妨げていた。例えば:
95-
96-
```cpp
97-
template<int *p> struct A {};
98-
int n;
99-
A<&n> a; // ok
100-
101-
constexpr int *p() { return &n; }
102-
A<p()> b; // error
103-
104-
constexpr int *q() { return nullptr; }
105-
A<q()> c; // ok!
106-
```
107-
108-
これまでの制限の歴史的な理由は、C++がこれまでポインタ、参照、またはメンバへのポインタ型の定数式のための十分に強力な仕様を持っていなかったことが原因だった。しかし、それはもはや当てはまらない。現状では、そのようなテンプレート引数を評価するには実装が必要だが、結果がnullでないことが判明した場合は結果を破棄する必要がある。
109-
110-
上記に加えて、リンケージを持つエンティティに対する制限はエクスポートされたテンプレートのアーティファクトであり、テンプレートタイプパラメータに対するリンケージ制限が削除されたときに削除された可能性がある。
111-
112-
(翻訳は正しくない可能性がある。正しくは、[原文](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4198.html)を参照。)
113-
114-
## 参照
115-
- [N4198 Allow constant evaluation for all non-type template arguments](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4198.html)
116-
- [N4268 Allow constant evaluation for all non-type template arguments](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4268.html)
117-
- [C++1z 全ての非型テンプレート引数の定数式評価を許可 - Faith and Brave - C++で遊ぼう](https://faithandbrave.hateblo.jp/entry/2016/10/27/180801)
1+
# 全ての非型テンプレート引数の定数式評価を許可
2+
3+
* cpp17[meta cpp]
4+
5+
## 概要
6+
C++17では、非型テンプレート引数(non-type template argument)で扱える型はとくに変わらないが、渡せる値についての制限緩和が行われる。
7+
8+
今回緩和されるのは、ポインタの値である。C++14までは、以下のような制限があった:
9+
10+
- 静的記憶域を持つ完全オブジェクトへのポインタ値もしくは参照、もしくは
11+
- ヌルポインタ値に評価される定数式、
12+
- ヌルメンバポインタ値に評価される定数式であること
13+
14+
つまり、`static`でないオブジェクトへのポインタは、ヌルポインタしか渡せなかった。
15+
16+
C++17ではこの制限が撤廃され、定数式で評価されるポインタならなんでも渡せるようになる。その許可される定数式での評価には、配列からポインタへの変換や、関数から関数ポインタへの変換、修飾の変換なども含まれる。
17+
18+
## 仕様
19+
直接の根拠は、次の記述が与えている。C++14での記述は削除され、C++17で置き換えられた。
20+
21+
[n4659](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf) [temp.arg.nontype]/2より
22+
23+
型ではないテンプレートパラメータのテンプレート引数は、テンプレートパラメータの型の変換された定数式になる。
24+
参照型またはポインタ型の非型テンプレートパラメータの場合、定数式の値は参照してはいけない(ポインタ型の場合は、次のアドレスにはならない)
25+
26+
- サブオブジェクト
27+
- 一時オブジェクト
28+
- 文字列リテラル
29+
- typeid式の結果
30+
- 定義済みの`__func__`変数
31+
32+
C++14からC++17にかけて、次の表のような変更があったと考えられる。[n4198](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4198.html)を参照。
33+
34+
| パラメータ種別 | C++14での引数の構文 |
35+
|---|---|
36+
| 整数または列挙 | 任意の定数式 |
37+
| ポインタ型 | 正確な構文と実体、配列、関数、リンケージを使用して静的記憶期間オブジェクトまたは関数を参照する。NULLポインタに評価される任意の定数式 |
38+
| 参照型 | 正確な構文とオブジェクト、関数、リンケージを使用して静的記憶期間オブジェクトまたは関数を参照する |
39+
| メンバーへのポインタ | 正確な構文と`&X::y` 、またはメンバーへのポインターが`NULL`に評価される任意の定数式 |
40+
| [`std::nullptr_t`](/reference/cstddef/nullptr_t.md) | 任意の定数式 |
41+
42+
から
43+
44+
| パラメータ種別 | C++17での引数の構文 |
45+
|---|---|
46+
| 整数または列挙 | 任意の定数式 |
47+
| ポインタ型 | 静的記憶期間を持つ、関数、または`NULL`ポインターを持つ完全なオブジェクトのアドレスに評価される任意の定数式 |
48+
| 参照型 | 静的記憶期間を持つ完全なオブジェクトまたは関数を参照する、`glvalue`に評価される任意の定数式。 |
49+
| メンバーへのポインタ | 任意の定数式 |
50+
| [`std::nullptr_t`](/reference/cstddef/nullptr_t.md) | 任意の定数式 |
51+
52+
##
53+
C++14では、以下のコードはコンパイルエラーとなるが、C++17では問題なくコンパイルされる。
54+
55+
```cpp example
56+
template<int* p>
57+
struct A {};
58+
59+
int n;
60+
A<&n> a; // ok
61+
62+
constexpr int* p() { return &n; }
63+
A<p()> b; // error in C++14
64+
65+
constexpr int* q() { return nullptr; }
66+
A<q()> c; // ok!
67+
68+
int main(){}
69+
```
70+
71+
### 出力例
72+
clang での出力例
73+
74+
C++14
75+
76+
```
77+
prog.cc:8:3: error: non-type template argument does not refer to any declaration
78+
A<p()> b; // error in C++14
79+
^~~
80+
prog.cc:1:15: note: template parameter is declared here
81+
template<int *p>
82+
^
83+
1 error generated.
84+
```
85+
86+
C++17
87+
88+
```
89+
```
90+
91+
## この機能が必要になった背景・経緯
92+
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4198.html を google 翻訳して編集
93+
94+
ポインター、参照、およびメンバーへのポインターに対する構文上の制限はぎこちなく、妥当なリファクタリングを妨げていた。例えば:
95+
96+
```cpp
97+
template<int *p> struct A {};
98+
int n;
99+
A<&n> a; // ok
100+
101+
constexpr int *p() { return &n; }
102+
A<p()> b; // error
103+
104+
constexpr int *q() { return nullptr; }
105+
A<q()> c; // ok!
106+
```
107+
108+
これまでの制限の歴史的な理由は、C++がこれまでポインタ、参照、またはメンバへのポインタ型の定数式のための十分に強力な仕様を持っていなかったことが原因だった。しかし、それはもはや当てはまらない。現状では、そのようなテンプレート引数を評価するには実装が必要だが、結果がnullでないことが判明した場合は結果を破棄する必要がある。
109+
110+
上記に加えて、リンケージを持つエンティティに対する制限はエクスポートされたテンプレートのアーティファクトであり、テンプレートタイプパラメータに対するリンケージ制限が削除されたときに削除された可能性がある。
111+
112+
(翻訳は正しくない可能性がある。正しくは、[原文](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4198.html)を参照。)
113+
114+
## 参照
115+
- [N4198 Allow constant evaluation for all non-type template arguments](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4198.html)
116+
- [N4268 Allow constant evaluation for all non-type template arguments](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4268.html)
117+
- [C++1z 全ての非型テンプレート引数の定数式評価を許可 - Faith and Brave - C++で遊ぼう](https://faithandbrave.hateblo.jp/entry/2016/10/27/180801)

0 commit comments

Comments
 (0)