LoginSignup
1
0

C++の配列に代入したいとき

Last updated at Posted at 2024-03-20

目的

例えばこんな構造体があって、メンバーの配列に値を設定したいとします。

今更変更なんて出来ないヘッダー.h
struct Hoge {
    /* 省略 */
    uint8_t hoge_color[4]; // RGBA
};

C++では良くあることです。

// 当然エラーになる
hoge.hoge_color = {255, 255, 255, 0};

こんなときRustであったならば…

もし、現状の開発環境がRustに対応していれば、悩む必要は無かったでしょう。

// 当然のように動く
hoge.hoge_color = [255, 255, 255, 0];

// これも行ける
let _ = std::mem::replace(&mut hoge.hoge_color, [255, 255, 255, 0]);

// サイズ不一致だとコンパイルエラー
hoge.hoge_color = [5, 4, 3, 2, 1, 0, 0, 0];

手遅れでなければ

もし、構造体の定義を変更できるのであれば、配列をstd::arrayに変更すべきです。

変更が間に合ったヘッダー.h
#include <array>
struct Hoge {
    /* 省略 */
    std::array<uint8_t, 4> hoge_color; // RGBA
};

// 動く
hoge.hoge_color = {255, 255, 255, 0};

std::arrayは、配列の代替として(十年以上前に)提案されたクラスです。
C++で配列からstd::arrayに移行しないのはバッドプラクティスです…と言いたいところですが、そもそもC++の存在そのものがバッドプラクティスでしょう。

しかしながら、このような解決策をとれないことも、C++では良くあることです。

解決策(暫定)

以下のように書けるよう、テンプレート関数を定義してみました。

set_array(hoge.hoge_color, {255, 255, 255, 0});

関数の中身は以下の通りです。

#include <algorithm>
#include <array>
template <typename T, size_t N>
inline void set_array(T (&dest)[N], const std::array<T, N> &src)
{
    std::copy(src.begin(), src.end(), std::begin(dest));
}

第一引数がよく分からないことになっています。この様にすることで、固定長配列を引数にできるらしいです。
第二引数は先程登場したstd::arrayですね。何故かこちらを使用しないと動かなかった…。

おしまい

  • C++には、昔ながらの代入出来ない配列と、代入できるstd::arrayがある
  • この状況でも入れる保険があるんですか代入出来ない配列も、テンプレートを利用することで、それっぽいことはできる
  • もっと良い書き方はないだろうか?
1
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0