前回は最終要素のひとつ先のアドレスを取得しました。今回は配列の最終要素のアドレスを取得してみます。

この場合も、元ネタにあるようなマクロを使えば求めることができます。

ひとつだけ注意しないといけないのは、配列の要素数がゼロの場合です。要素数がゼロの配列というのは本当は存在しないのですが、GCCなどでは普通に作れてしまいます。サイズがゼロの場合に上記のマクロを使うと未定義の動作になってしまいますので、先に要素数が1以上であることをチェックしておいた方がいいでしょう。

そういったことも盛り込んだ形で、次のような関数を作るのもよいでしょう。

要素数のチェックはしていませんが、これだけで要素数ゼロの配列を渡そうとするとコンパイルエラーになるようです(GCCおよびClangで確認しました)。もちろん、C++11以降であればconstexprにすることも可能です。

C++11以降であれば、std::end関数(またはstd::cend関数)とstd::prev関数を組み合わせて実現することもできます。

std::end関数とstd::prev関数であればstd::vectorなどのコンテナにも使うことができます。ただ、配列の場合は上記でかまいませんが、コンテナの場合は要素がゼロでないことを別途チェックする必要がありそうです。

C++17以降であれば、std::size関数またはstd;;empty関数が使えますので、次のように書くことができます。

返却値の型も、まともに書くとdecltypeを使って、たとえばdecltype(std::end(c))のように書く必要がありますが、ここは簡単にautoだけにしています。


元ネタ

↑ 3. 配列に関するテンプレート