0Pricing
C++ Academy · レッスン

関数へのspanの渡し方

柔軟なAPIを記述します

「関数へのspanの渡し方」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。

1つの関数で多くのコンテナーに対応

std::spanを受け取る関数は、配列、vector、生のバッファーを同じように受け取れます。テンプレートやオーバーロードは必要ありません。

#include <iostream>
#include <span>
#include <vector>
#include <array>
int sum(std::span<const int> s) {
    int t = 0; for (int x : s) t += x; return t;
}
int main() {
    std::vector<int> v = {1, 2, 3};
    std::array<int, 2> a = {4, 5};
    std::cout << sum(v) << " " << sum(a) << "\n";
}

サイズ引数が不要

従来のC形式APIでは、ポインターとサイズを別々に渡します。spanはこの2つをまとめるため、長さの不一致によるバグを防げます。

#include <iostream>
#include <span>
void printAll(std::span<const int> s) {
    for (int x : s) std::cout << x << " ";
    std::cout << "\n";
}
int main() {
    int buf[] = {7, 8, 9};
    printAll(buf); // size inferred
}

読み取り専用にはconst span

std::span<const T>を使用すると、関数が呼び出し元のデータを変更しないことを保証できます。

#include <iostream>
#include <span>
int maxOf(std::span<const int> s) {
    int m = s[0];
    for (int x : s) if (x > m) m = x;
    return m;
}
int main() {
    int data[] = {3, 9, 4};
    std::cout << maxOf(data) << "\n"; // 9
}

編集には変更可能なspan

constではないspanを使うと、関数から呼び出し元の要素を直接変更できます。

#include <iostream>
#include <span>
#include <vector>
void doubleAll(std::span<int> s) {
    for (int& x : s) x *= 2;
}
int main() {
    std::vector<int> v = {1, 2, 3};
    doubleAll(v);
    std::cout << v[2] << "\n"; // 6
}

テンプレートの肥大化を回避

spanがなければ、コンテナー型をテンプレート引数にすることになり、多数のインスタンスが生成される可能性があります。spanなら、どのコンテナーにもそのまま使える1つの具体的なシグネチャで済みます。

コピーを回避

spanを渡しても要素はコピーされず、関数に渡されるのはポインターと長さだけです。

#include <iostream>
#include <span>
#include <vector>
size_t count(std::span<const int> s) { return s.size(); }
int main() {
    std::vector<int> big(1000, 0);
    std::cout << count(big) << "\n"; // no copy of 1000 ints
}

空のspanも問題なし

関数は空のspanを適切に処理できるようにしてください。size()は0になり、範囲ベースのループは0回だけ実行されます。

#include <iostream>
#include <span>
int sum(std::span<const int> s) { int t = 0; for (int x : s) t += x; return t; }
int main() {
    std::span<const int> empty;
    std::cout << sum(empty) << "\n"; // 0
}

値渡し

spanは非常に小さいため、参照ではなく値渡ししてください。ポインターと長さのコピーは実質的にコストがかかりません。

constの意図を明示

span<const T>とspan<T>のどちらを選ぶかによって、データを変更できるかどうかを呼び出し元に一目で伝えられます。

所有権は呼び出し元に残る

コンテナーの所有権は呼び出し元に残ります。spanは呼び出し中だけコンテナーを借用します。関数は呼び出しが終わった後までspanを保持してはいけません。

現代的なAPIのスタイル

spanを受け取ることは、連続したデータを扱う関数を記述する現代的で慣用的な方法です。柔軟で安全、かつコピーも発生しません。

理解度チェック

spanの関数への渡し方についての理解度を確認してください。

まとめ

spanを関数に渡す方法について学びました。

  • 1つのシグネチャで、配列、vector、バッファーを受け取れます。
  • 読み取り専用にはspan<const T>を、直接編集する場合はspan<T>を使用します。
  • 値渡ししてもコピーは発生しません。
  • 所有権は呼び出し元に残るため、呼び出し後までspanを保持してはいけません。

よくある質問

「関数へのspanの渡し方」レッスンは無料ですか?

はい。「関数へのspanの渡し方」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。

「関数へのspanの渡し方」で何を学びますか?

柔軟なAPIを記述します ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C++ Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「関数へのspanの渡し方」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC++ Academyレッスンでコードを書いて実行できますか?

はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 固定長std::array
  2. std::spanの基礎
  3. 関数へのspanの渡し方
  4. 範囲とサブスパン
← C++ Academyに戻る