Skip to content

Commit 9d2eae5

Browse files
committed
reflection : define〜系の解説を強化
1 parent 7424626 commit 9d2eae5

3 files changed

Lines changed: 45 additions & 14 deletions

File tree

GLOBAL_QUALIFY_LIST.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@
234234
* <memory_resource>[link /reference/memory_resource.md]
235235
* <meta>[link /reference/meta.md]
236236
* std::meta::info[link /reference/meta/info.md]
237+
* std::define_static_array[link /reference/meta/define_static_array.md]
238+
* std::define_static_object[link /reference/meta/define_static_object.md]
239+
* std::define_static_string[link /reference/meta/define_static_string.md]
237240
* <mutex>[link /reference/mutex.md]
238241
* std::lock_guard[link /reference/mutex/lock_guard.md]
239242
* std::mutex[link /reference/mutex/mutex.md]

lang/cpp26/reflection.md

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -263,23 +263,52 @@ template for (constexpr auto m :
263263
264264
265265
## `define_static_string` / `define_static_array` / `define_static_object`
266-
これらは、コンパイル時に計算した値を静的ストレージに配置し、実行時に使用可能にするための関数群である。[`std::define_static_string()`](/reference/meta/define_static_string.md)は文字列を、[`std::define_static_array()`](/reference/meta/define_static_array.md)は配列を、[`std::define_static_object()`](/reference/meta/define_static_object.md)はオブジェクトをそれぞれ静的ストレージに配置する。これらは`<meta>`ヘッダで提供されるが、`std`名前空間に定義される(`std::meta`名前空間ではない)。
266+
これらは、コンパイル時に計算した値を静的ストレージに配置し、実行時に使用可能にするための関数群である。これらは`<meta>`ヘッダで提供されるが、`std`名前空間に定義される(`std::meta`名前空間ではない)。
267+
268+
| 関数 | 説明 |
269+
|------|------|
270+
| [`std::define_static_string()`](/reference/meta/define_static_string.md) | コンパイル時文字列を静的ストレージに配置し、ヌル終端の`const CharT*`を返す |
271+
| [`std::define_static_array()`](/reference/meta/define_static_array.md) | コンパイル時配列を静的ストレージに配置し、[`std::span`](/reference/span/span.md)`<const T>`を返す |
272+
| [`std::define_static_object()`](/reference/meta/define_static_object.md) | コンパイル時オブジェクトを静的ストレージに配置し、`const T*`を返す |
273+
274+
### 主な用途
275+
これらの関数は、以下のようなリフレクションの典型的なユースケースで頻繁に使用される。
276+
277+
#### (1) `template for`文のrangeを静的配列に変換する
278+
[`members_of()`](/reference/meta/members_of.md)や[`enumerators_of()`](/reference/meta/enumerators_of.md)などのメタ関数は`std::vector<std::meta::info>`を返すが、`std::vector`は動的メモリ確保を伴うため[`template for`文](/lang/cpp26/expansion_statements.md)のrangeとして直接使用できない。[`std::define_static_array()`](/reference/meta/define_static_array.md)で静的ストレージに配置した[`std::span`](/reference/span/span.md)に変換することで、`template for`文で走査できるようになる。
267279
268280
```cpp
269-
// コンパイル時に計算した文字列を実行時に使用する
270-
template <typename E>
271-
requires std::is_enum_v<E>
272-
constexpr std::string_view enum_to_string(E value) {
273-
template for (constexpr auto e : std::define_static_array(std::meta::enumerators_of(^^E))) {
274-
if (value == [:e:]) {
275-
return std::meta::identifier_of(e);
276-
}
277-
}
278-
return "<unknown>";
281+
template for (constexpr auto m :
282+
std::define_static_array(std::meta::nonstatic_data_members_of(^^S,
283+
std::meta::access_context::unchecked()))) {
284+
// mを使った処理
279285
}
280286
```
281-
* std::meta::enumerators_of[link /reference/meta/enumerators_of.md]
282-
* std::meta::identifier_of[link /reference/meta/identifier_of.md]
287+
* std::meta::nonstatic_data_members_of[link /reference/meta/nonstatic_data_members_of.md]
288+
* std::meta::access_context::unchecked[link /reference/meta/access_context/unchecked.md]
289+
290+
#### (2) コンパイル時文字列を実行時に返す
291+
コンパイル時に構築した[`std::string`](/reference/string/basic_string.md)[`std::string_view`](/reference/string_view/basic_string_view.md)は、そのままでは実行時にアクセスできない(一時オブジェクトの寿命が尽きる、または`consteval`型の制約)。[`std::define_static_string()`](/reference/meta/define_static_string.md)で静的ストレージに配置することで、ヌル終端の`const char*`として実行時まで持ち越せる。
292+
293+
ただし、[`identifier_of()`](/reference/meta/identifier_of.md)のように既に`string_view`を返す関数は、そのまま戻り値として返せる場合もある(静的ストレージに存在する識別子の文字列を指すため)。
294+
295+
#### (3) アノテーションの文字列リテラル
296+
アノテーションの式は構造的型でなければならず、文字列リテラルを直接メンバとして持つと寿命の問題が生じる可能性がある。[`std::define_static_string()`](/reference/meta/define_static_string.md)で静的ストレージに配置することで、安全に`const char*`メンバに格納できる。
297+
298+
```cpp
299+
struct Name { const char* value; };
300+
struct [[=Name{std::define_static_string("ラベル")}]] Tagged {};
301+
```
302+
303+
#### (4) コンパイル時に構築したオブジェクトを実行時に参照する
304+
コンパイル時に構築した任意のオブジェクトを静的ストレージに配置し、実行時にポインタで参照するには[`std::define_static_object()`](/reference/meta/define_static_object.md)を使用する。
305+
306+
```cpp
307+
struct Config { int width; int height; };
308+
309+
// コンパイル時に構築したConfigオブジェクトを静的ストレージに配置
310+
constexpr const Config* config = std::define_static_object(Config{1920, 1080});
311+
```
283312

284313

285314
## リフレクションのエラー処理

reference/meta/is_string_literal.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ int main() {
5959
}
6060
```
6161
* std::is_string_literal[color ff0000]
62-
* std::define_static_string[link define_static_string.md]
6362

6463
### 出力
6564
```

0 commit comments

Comments
 (0)