std::array (c++11)

std::array を試します。

 

 

 

 

1. 始めに

[概要]

ja.cppreference.com に記載されているサンプルプログラムから作成してみます。
(少し変更しています。)

https://ja.cppreference.com/w/cpp/container/array

 

[環境]

コンパイラ : Visual Studio 2022, Version 17.2.4
  Visual Studio 2019 pro., Version 16.7.1
OS: Windows11 home, 21H2
  Windows10 home, Version 1909

 

[プログラムソース]

#include <iostream>
#include <string>
#include <algorithm>
#include <array>

int main()
{
    // 構築は集成体初期化を使用します。
    std::array<int, 3> a1{ {3, 1, 2} }; // CWG 1270 の改訂前の C++11 では二重の波括弧が必要です
                                        // (改定後の C++11 および C++14 以上では必要ありません)。
    std::array<int, 3> a2 = { 1, 2, 3 };  // = の後では必要ありません。
    std::array<std::string, 2> a3 = { std::string("a"), "b" };

    // コンテナ操作がサポートされています。
    // a1
    std::sort(a1.begin(), a1.end());
    std::copy(a1.begin(), a1.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
    // a2
    std::reverse_copy(a2.begin(), a2.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';

    // 範囲 for ループがサポートされています。
    // a3
    for (const auto& s : a3) {
        std::cout << s << ' ';
    }
    
    return EXIT_SUCCESS;
}

[出力]

1 2 3
3 2 1
a b

 

 

2. std::array で二次元配列

 c++11では、std::array はあるけれども std::multi_array がありません。つまり boost::multi_array に相当するコンテナが無いのです。
しょうがないので std::array で multi_array 相当のことができることを以下で確認してみます。たぶん下記のような内容で等価のことをできると判断し、不要と判断されたのかと。
それからイニシャライザーリストの書き方ですが、下記の通り中括弧が3階層必要です。一番外側の中括弧は不要に思えるのですが、これを省略するとエラーになってしまいます。

 

[環境]

コンパイラ : Visual Studio 2022, Version 17.2.4
  Visual Studio 2010  
OS: Windows11 home, 21H2
  Windows7 Proffesional 64bit 日本語版  

 

[プログラムソース]

#include <iostream> // cout, endl
#include <string>   // string, getline
#include <array>    // array

using namespace std;

int main(int argc, char* argv[])
{
    const size_t                        SizeX = 5 ;
    const size_t                        SizeY = 3 ;
    array<array< int, SizeX >, SizeY>   hoge = {
                                                   {
                                                       { 0, 1, 2, 3, 4},
                                                       { 1, 2, 3, 4, 5},
                                                       { 2, 3, 4, 5, 6}
                                                   },
                                               };

    /*========*/
    /* 前処理 */
    /*========*/

    /*========*/
    /* 処理部 */
    /*========*/
    for ( size_t y=0; y<hoge.size(); ++y ){
        for ( size_t x=0; x<hoge[y].size(); ++x ){
            cout << hoge[y][x] << " " ;
        }
        cout << endl;
    }

    /*========*/
    /* 後処理 */
    /*========*/
    {
        cout << "HIT [Enter] KEY !! " ;
        string  str ;
        getline( std::cin, str );
    }
    return EXIT_SUCCESS;
}

 

[実行結果]

0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
HIT [Enter] KEY !!

 

機能としてこれで十分に見えます。固定長配列なので、関数なんかで引数として渡す場合も typedef すればまったく問題を感じませんね。

 

 

3. N次元配列

同じ要領でN次元の配列も作成可能です。
が、型の宣言が std::array< std::array< std::array< ・・・, N3>, N2>, N1> という感じになって面倒です。
何か良い方法がないかとインターネットを検索していたら... よさそうなネタがありました。
結局展開されれば同じことなのですが、わかりやすいこと、template の使い方の良い勉強になること、で素晴らしいコードと思いました。勉強になります。
以下に紹介します。

引用元: http://koturn.hatenablog.com/entry/2018/08/02/000000

 

[環境]

コンパイラ : Visual Studio 2022, Version 17.2.4
  Visual Studio 2010  
OS: Windows11 home, 21H2
  Windows7 Proffesional 64bit 日本語版  

 

[プログラムソース]

#include <iostream>
#include <string>
#include <array>


template<typename T, std::size_t N, std::size_t... Extents>
struct extents_expander
    : extents_expander<std::array<T, N>, Extents...>
{};  // struct extents_expander

template<typename T, std::size_t N>
struct extents_expander<T, N>
{
    using type = std::array<T, N>;
};  // struct extents_expander

template<typename T, std::size_t... Extents>
struct ndarray_helper
{
    using type = typename extents_expander<T, Extents...>::type;
};  // struct ndarray_helper

template<typename T, std::size_t N, std::size_t... Extents>
struct ndarray_helper<T[N], Extents...>
{
    using type = typename ndarray_helper<T, N, Extents...>::type;
};  // struct ndarray_helper

template<typename T>
using NdArray = typename ndarray_helper<T>::type;


int main()
{
    const size_t X = 10;
    const size_t Y = 20;
    const size_t Z = 30;

    static NdArray<int[X][Y][Z]> array;     // NdArray<int[X][Y][Z]> 
                                            // = ndarray_helper<int[X][Y][Z]>
                                            // = ndarray_helper<int[Y][Z], X>
                                            // = ndarray_helper<int[Z], Y, X>
                                            // = ndarray_helper<int, Z, Y, X>
                                            // = extents_expander<int, Z, Y, X>
                                            // = extents_expander<std::array<int, Z>, Y, X>
                                            // = extents_expander<std::array< std::array<int, Z>, Y>, X>
                                            // = std::array<std::array< std::array<int, Z>, Y>, X>

    int count = 0;

    for (int i = 0; i < X; i++) {
        for (int j = 0; j < Y; j++) {
            for (int k = 0; k < Z; k++) {
                array[i][j][k] = count++;
            }
        }
    }

    for (auto x : array) {
        for (auto y : x) {
            std::copy(y.begin(), y.end(), std::ostream_iterator<int>(std::cout, " "));
            std::cout << std::endl;
        }
    }

    return EXIT_SUCCESS;
}

[実行結果]

割愛

 

ライセンス

本ページの情報は、特記無い限り下記 MIT ライセンスで提供されます。

MIT License

Copyright (c) 2012-2022 Kinoshita Hidetoshi

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 

 

 

参考

 


 

変更履歴

2022-06-22 - 評価環境として VS2022、Windows11 を追加
2020-08-18 - 「3. N次元配列」を追加。
2020-08-12 - 画面構成をメンテ。vector, deque の書式と統一。
- "1.始めに" を刷新。
2012-02-26 - 新規作成

 

Programming Items トップページ

プライバシーポリシー