@@ -35,6 +35,9 @@ constexpr span(const span& other) noexcept = default; // (8) C++20
3535template <class OtherElementType, size_t OtherExtent>
3636constexpr explicit(extent != dynamic_extent && OtherExtent == dynamic_extent)
3737 span(const span<OtherElementType, OtherExtent>& s) noexcept; // (9) C++20
38+
39+ constexpr explicit(extent != dynamic_extent)
40+ span(std::initializer_list<value_type> il); // (10) C++26
3841```
3942* size_t[link /reference/cstddef/size_t.md]
4043* array[link /reference/array/array.md]
@@ -57,6 +60,7 @@ constexpr explicit(extent != dynamic_extent && OtherExtent == dynamic_extent)
5760 - 動的な要素数をもつ`span`同士の変換
5861 - `span<T>`から`span<const T>`への変換
5962 - バイト数が同じ暗黙の型変換が可能な要素型をもつ`span`同士の変換
63+ - (10) : 初期化子リストから`span`オブジェクトを構築する
6064
6165
6266## テンプレートパラメータ制約
@@ -88,6 +92,9 @@ constexpr explicit(extent != dynamic_extent && OtherExtent == dynamic_extent)
8892- (9) :
8993 - `extent ==` [`dynamic_extent`](/reference/span/dynamic_extent.md) `|| OtherExtent ==` [`dynamic_extent`](/reference/span/dynamic_extent.md) `|| extent == OtherExtent`が`true`であること (受け取り側が[`dynamic_extent`](/reference/span/dynamic_extent.md)を持っていれば任意の`Extent`から変換できる)
9094 - `OtherElementType(*)[]`型が`ElementType(*)[]`型に変換可能であること
95+ - (10) :
96+ - [`is_const_v`](/reference/type_traits/is_const.md)`<element_type>`が`true`であること
97+ - (`std::span<const T>`に対してのみ使用できる)
9198
9299
93100## 事前条件
@@ -106,6 +113,8 @@ constexpr explicit(extent != dynamic_extent && OtherExtent == dynamic_extent)
106113 - [`std::is_const_v`](/reference/type_traits/is_const.md)`<element_type>` が `false`であるとき、型 `R` はコンセプト [`std::ranges::borrowed_range`](/reference/ranges/borrowed_range.md) のモデルであること
107114- (9) :
108115 - `extent`が[`dynamic_extent`](/reference/span/dynamic_extent.md)と等値でない場合、`extent`は[`s.size()`](size.md)と等値になる
116+ - (10) :
117+ - `extent`が[`dynamic_extent`](/reference/span/dynamic_extent.md)と等値でない場合、`extent`は[`il.size()`](/reference/initializer_list/initializer_list/size.md)と等値になる
109118
110119
111120## 効果
@@ -114,6 +123,7 @@ constexpr explicit(extent != dynamic_extent && OtherExtent == dynamic_extent)
114123- (4), (5), (6) : 範囲`[`[`data`](/reference/iterator/data.md)`(arr),` [`data`](/reference/iterator/data.md)`(arr) + N)`を参照する`span`オブジェクトを構築する
115124- (7) : 範囲`[std::ranges::data(r), std::ranges::data(r) + std::ranges::size(r))`を参照する`span`オブジェクトを構築する
116125- (9) : 範囲`[s.`[`data()`](data.md)`, s.`[`data()`](data.md) `+ s.`[`size()`](size.md)`)`を参照する`span`オブジェクトを構築する
126+ - (10) : 範囲`[il.`[`begin()`](/reference/initializer_list/initializer_list/begin.md)`, il.`[`begin()`](/reference/initializer_list/initializer_list/begin.md) `+ il.`[`size()`](/reference/initializer_list/initializer_list/size.md)`)`を参照する`span`オブジェクトを構築する
117127
118128
119129## 事後条件
@@ -130,10 +140,20 @@ constexpr explicit(extent != dynamic_extent && OtherExtent == dynamic_extent)
130140
131141
132142## 計算量
133- - (1)-(9) : 定数時間
143+ - (1)-(10) : 定数時間
144+
145+
146+ ## この機能が必要になった背景・経緯
147+ - (10) :
148+ - [`std::string_view`](/reference/string_view/basic_string_view.md)が文字列リテラル (たとえば`"abc"`) をとれるのと同様に、`std::span`クラスも[`std::initializer_list`](/reference/initializer_list/initializer_list.md)をとれるようにした
149+
150+
151+ ## 備考
152+ - (10) : `std::span<const int> v = {1, 2, 3};` のような使い方は初期化子リストの寿命が尽きてしまうので注意。関数のパラメータを`span`として受け取るような使い方が想定される
134153
135154
136155## 例
156+ ### 基本的な使い方 (C++20)
137157```cpp example
138158#include <cassert>
139159#include <span>
@@ -261,8 +281,47 @@ int main()
261281* str.size()[ link /reference/string/basic_string/size.md]
262282* str.data()[ link /reference/string/basic_string/data.md]
263283
264- ### 出力
284+ #### 出力
285+ ```
286+ ```
287+
288+
289+ ### 初期化子リストからspanを構築する (C++26)
290+ ``` cpp example
291+ #include < iostream>
292+ #include < span>
293+ #include < vector>
294+
295+ void print_list (std::span<const int > s) {
296+ bool first = true;
297+ for (const int& x : s) {
298+ if (first) {
299+ first = false;
300+ }
301+ else {
302+ std::cout << ',';
303+ }
304+ std::cout << x;
305+ }
306+ std::cout << std::endl;
307+ }
308+
309+ int main()
310+ {
311+ std::vector<int > v = {1, 2, 3, 4, 5};
312+ print_list(v);
313+
314+ print_list({{3, 1, 4}}); // C++20からOK
315+ print_list({3, 1, 4}); // C++26からOK
316+ }
317+ ```
318+
319+
320+ #### 出力
265321```
322+ 1,2,3,4,5
323+ 3,1,4
324+ 3,1,4
266325```
267326
268327## バージョン
@@ -283,3 +342,5 @@ int main()
283342- [P1394R4 Range constructor for `std::span`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1394r4.pdf)
284343- [P1976R2 Fixed-size `span` construction from dynamic range](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1976r2.html)
285344- [P2117R0 C++ Standard Library Issues Resolved Directly In Prague](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2117r0.html)
345+ - [P2447R6 `std::span` over an initializer list](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2447r6.html)
346+ - C++26から初期化子リストをとるコンストラクタが追加された
0 commit comments