もう怖くない!Qt QList::front()のエラー解決と代替メソッド詳解
QListとは?
まず、QList
はQtが提供するジェネリックコンテナクラスの一つです。これは、特定の型のオブジェクトをリスト形式で格納するために設計されています。C++標準ライブラリのstd::vector
やstd::list
に似ていますが、Qt独自の利点や統合性を持っています。
front()
関数とは?
front()
関数は、QList
の最初の要素への参照を返します。つまり、リストの先頭にあるデータに直接アクセスするための方法を提供します。
<T>
とは?
<T>
はテンプレートパラメータです。これは、QList
が任意のデータ型を格納できることを示しています。例えば、QList<int>
であれば整数を、QList<QString>
であれば文字列を格納します。<T>::reference
は、そのテンプレートパラメータT
の参照型を意味します。
reference
とは?
reference
(参照)はC++の概念で、既存のオブジェクトの別名のようなものです。front()
が参照を返すということは、単に要素のコピーを返すのではなく、リスト内の実際の要素自体にアクセスできることを意味します。これにより、返された参照を介してリストの最初の要素を直接変更することが可能になります。
<T>::reference QList::front()
は、
QList
に格納されている任意の型T
の、- 最初の要素への、
- 参照を返す関数です。
使用例
#include <QList>
#include <QDebug>
int main() {
QList<int> myList;
myList.append(10);
myList.append(20);
myList.append(30);
// front()を使って最初の要素にアクセスし、表示する
qDebug() << "最初の要素:" << myList.front(); // 出力: 最初の要素: 10
// front()が返す参照を使って最初の要素を変更する
myList.front() = 5;
qDebug() << "変更後の最初の要素:" << myList.front(); // 出力: 変更後の最初の要素: 5
// リスト全体を表示して確認
qDebug() << "リスト全体:" << myList; // 出力: リスト全体: QList(5, 20, 30)
// リストが空の場合にfront()を呼び出すと未定義の動作になるので注意
QList<int> emptyList;
// qDebug() << emptyList.front(); // これはクラッシュする可能性があります!
// 呼び出す前にQList::isEmpty()で確認するのが安全です。
if (!emptyList.isEmpty()) {
qDebug() << emptyList.front();
} else {
qDebug() << "リストは空です。";
}
return 0;
}
- 同様に、
QList::back()
関数は最後の要素への参照を返します。 QList::front()
を呼び出す前に、リストが空でないことを確認することが非常に重要です。空のリストに対してfront()
を呼び出すと、未定義の動作(通常はクラッシュ)を引き起こす可能性があります。QList::isEmpty()
関数を使用して、呼び出し前にリストが空でないことを確認する習慣をつけることを強くお勧めします。
最も頻繁に発生するエラーは、リストが空の状態でfront()
を呼び出すことです。
エラー: 空のQListに対するfront()呼び出し (最も一般的)
問題
これは、おそらくQList::front()
を使用する上で最も一般的な、そして最も危険なエラーです。リストに要素が一つもない状態でfront()
を呼び出すと、未定義の動作(Undefined Behavior)を引き起こします。これは通常、アプリケーションのクラッシュ(セグメンテーション違反など)につながります。
なぜ起こるのか?
front()
は「最初の要素への参照」を返そうとしますが、最初の要素が存在しないため、無効なメモリ位置を指す参照を返そうとします。その無効なメモリ位置にアクセスしようとすると、プログラムが異常終了します。
悪いコード例
QList<int> myList; // 空のリスト
// ... 何も追加しない ...
int value = myList.front(); // !!! ここでクラッシュする可能性が高い !!!
トラブルシューティング/解決策
front()
を呼び出す前に、必ずQList::isEmpty()
関数を使ってリストが空でないことを確認してください。
良いコード例
QList<int> myList;
// myList.append(10); // 要素を追加する場合
if (!myList.isEmpty()) {
int value = myList.front();
qDebug() << "最初の要素: " << value;
} else {
qDebug() << "リストは空なので、最初の要素にはアクセスできません。";
// 必要に応じてエラー処理や代替ロジックをここに記述
}
デバッグのヒント
クラッシュが発生した場合、スタックトレースを確認してください。多くの場合、QList::front()
の呼び出し元、またはその近くの場所でエラーが発生していることが示されます。プログラムの実行パスをたどり、front()
が呼び出される直前にリストが空になっていないかを確認します。
エラー: constなQListオブジェクトに対する非constなfront()の呼び出し
問題
もしQList
オブジェクトがconst
として宣言されている場合、front()
はconst T&
(const参照)を返します。このconst参照を通して要素を変更しようとすると、コンパイルエラーが発生します。
なぜ起こるのか?
const
オブジェクトは変更が許されないため、そのオブジェクトのメンバ関数が返す参照も、オブジェクトを変更しないことを保証するためにconst
である必要があります。
悪いコード例
void printAndModify(const QList<int>& list) {
qDebug() << "最初の要素 (const):" << list.front();
// list.front() = 5; // コンパイルエラー: assignment of read-only location
}
// ... main関数などから呼び出す ...
QList<int> myNumbers;
myNumbers.append(1);
printAndModify(myNumbers);
トラブルシューティング/解決策
- 変更する必要がなく、単に値を取得したい場合
const T&
として値を受け取るようにします。 - constなQListを変更する必要がある場合
関数シグネチャからconst
修飾子を削除するか、const_cast
を使用しない限り、元のリストを変更することはできません。(const_cast
は通常、避けるべきです)
良いコード例
void printOnly(const QList<int>& list) {
if (!list.isEmpty()) {
const int& value = list.front(); // const参照として受け取る
qDebug() << "最初の要素 (const):" << value;
} else {
qDebug() << "リストは空です。";
}
}
void modifyList(QList<int>& list) { // constではない参照でリストを受け取る
if (!list.isEmpty()) {
list.front() = 5; // ここで変更が可能
qDebug() << "変更後の最初の要素:" << list.front();
} else {
qDebug() << "リストは空です。";
}
}
// ... main関数などから呼び出す ...
QList<int> myNumbers;
myNumbers.append(10);
printOnly(myNumbers); // 変更はしない
modifyList(myNumbers); // 変更する
意図しないデータ変更
問題
front()
は参照を返すため、その参照を通してリストの最初の要素を直接変更することができます。これが意図しない副作用を引き起こすことがあります。
なぜ起こるのか? 参照は元のオブジェクトの別名なので、参照に対する操作は元のオブジェクトに直接影響します。
例
QList<int> myData;
myData.append(100);
myData.append(200);
int& firstElementRef = myData.front(); // 参照を取得
firstElementRef = 50; // 参照を通じて要素を変更
qDebug() << myData.at(0); // 出力: 50 (変更されている)
トラブルシューティング/解決策
- 変更を意図していることを明確にする
コードコメントなどで、参照を通じて変更が行われることを明示します。 - 変更を意図しない場合
front()
が返す参照をconst
参照として受け取るか、QList::at(0)
(これもconst
参照を返す)を使用することを検討してください。これにより、意図しない変更を防ぐことができます。
推奨される取得方法(変更しない場合)
QList<int> myData;
myData.append(100);
if (!myData.isEmpty()) {
const int& value = myData.front(); // const参照として受け取る
// value = 50; // これはコンパイルエラーになる
qDebug() << "値: " << value;
}
イテレータの無効化
問題
QList
は暗黙の共有(Implicit Sharing)メカニズムを持っています。しかし、front()
自体がイテレータを直接無効化することはありません。むしろ、QList
に対して要素の追加や削除を行った場合、既存のイテレータ(特にQList::iterator
)は無効になる可能性があります。front()
で得た参照は、リストが変更された後もそのメモリ位置を指し続ける可能性がありますが、そのメモリ位置にあるデータがもはやリストの最初の要素でない、あるいは解放されている、といった問題が発生する可能性があります。
なぜ起こるのか?
QList
の内部データ構造が再配置されたり、要素が削除されたりすると、以前に取得した参照が指すメモリが有効でなくなるか、異なるデータを指すようになるためです。
例(間接的な問題)
QList<QString> names;
names.append("Alice");
names.append("Bob");
QString& firstRef = names.front(); // "Alice"への参照を取得
names.prepend("Charlie"); // 先頭に要素を追加 -> "Alice"はもう最初の要素ではない
qDebug() << firstRef; // "Alice"が出力されるかもしれないが、これはもうリストのfrontではない。
// リストが内部的に再割り当てされた場合、これはダングリング参照になる可能性もある。
トラブルシューティング/解決策
- リストの要素を頻繁に追加・削除しつつ、最初の要素にアクセスする必要がある場合は、各操作の後に
front()
を再呼び出しするか、別のコンテナ(例:QQueue
やQStack
など、front()
やtop()
が安定しているもの)を検討する方が適切かもしれません。 - リストを変更する操作の後で、再度
front()
を呼び出して新しい参照を取得するようにします。 front()
から取得した参照は、リストの構造を変更する操作(append()
,prepend()
,removeAt()
,clear()
など)を行うと無効になる可能性がある、と認識してください。
QList::front()
は強力なツールですが、その参照セマンティクスとリストの空状態に対する脆弱性を理解することが重要です。
- リスト構造が変更された後には、既存の
front()
で得た参照は無効になる可能性があると認識する。 - 参照を通じて要素を変更できることを意識し、意図しない変更を防ぐ。
const
オブジェクトに対してfront()
を使う場合は、返される参照もconst
であることを理解する。- 常に
isEmpty()
でチェック! これが最も重要です。
QList::front()
は、リストの最初の要素への参照を返す便利な関数です。この「参照」というのがポイントで、返された参照を通じて直接要素の値を読み取ったり、変更したりできます。
以下に、いくつかの具体的なプログラミング例とその解説を示します。
例1: 最初の要素の値を読み取る
最も基本的な使い方です。リストが空でないことを確認してからfront()
を呼び出すのが鉄則です。
#include <QList>
#include <QDebug> // デバッグ出力用
int main() {
QList<int> numbers;
numbers.append(10);
numbers.append(20);
numbers.append(30);
// リストが空でないか確認することが非常に重要!
if (!numbers.isEmpty()) {
// front()は参照を返すので、直接変数に代入できる
int firstValue = numbers.front();
qDebug() << "最初の要素の値: " << firstValue; // 出力: 最初の要素の値: 10
// const参照として受け取ることも可能。これにより、誤って値を変更するのを防げる
const int& firstValueRef = numbers.front();
qDebug() << "const参照で取得した最初の要素の値: " << firstValueRef; // 出力: const参照で取得した最初の要素の値: 10
// firstValueRef = 99; // コンパイルエラー: const参照なので変更できない
} else {
qDebug() << "リストは空です。";
}
QList<QString> names;
names.append("Alice");
names.append("Bob");
if (!names.isEmpty()) {
QString firstName = names.front();
qDebug() << "最初の名前: " << firstName; // 出力: 最初の名前: "Alice"
}
return 0;
}
解説
const int&
として受け取ることで、その参照を通じて値を変更できないようにできます。これは、単に値の読み取りだけを目的とする場合に安全な方法です。- この返り値を直接
int
型の変数に代入すると、要素の値がコピーされます。 numbers.front()
はQList<int>
の場合、int&
(int
への参照)を返します。
例2: 最初の要素の値を変更する
front()
が参照を返す最大の利点の一つです。リストの最初の要素を直接更新できます。
#include <QList>
#include <QDebug>
int main() {
QList<double> temperatures;
temperatures.append(25.5);
temperatures.append(28.1);
temperatures.append(22.0);
qDebug() << "変更前リスト: " << temperatures; // 出力: 変更前リスト: QList(25.5, 28.1, 22)
if (!temperatures.isEmpty()) {
// front()が返す参照を通じて、直接最初の要素の値を変更
temperatures.front() = 26.0;
qDebug() << "変更後リスト: " << temperatures; // 出力: 変更後リスト: QList(26, 28.1, 22)
} else {
qDebug() << "リストは空です。";
}
QList<QString> messages;
messages.append("Hello");
messages.append("World");
qDebug() << "変更前メッセージ: " << messages; // 出力: 変更前メッセージ: QList("Hello", "World")
if (!messages.isEmpty()) {
// QStringオブジェクトの参照を取得し、その参照を通じて値を変更
messages.front() = "Hi there";
qDebug() << "変更後メッセージ: " << messages; // 出力: 変更後メッセージ: QList("Hi there", "World")
}
return 0;
}
解説
QString
のような複雑なオブジェクトの場合も同様に、参照を通じてそのオブジェクトの値を変更できます。temperatures.front() = 26.0;
の行では、front()
が返すdouble&
(double
への参照)を利用して、リスト内の最初の要素の値を直接26.0
に更新しています。これはtemperatures[0] = 26.0;
と同じ効果を持ちます。
例3: front()
を使う際の一般的な落とし穴と安全な使い方
最も重要なのは、空のリストに対するfront()
の呼び出しを避けることです。これは未定義の動作を引き起こし、クラッシュの原因になります。
#include <QList>
#include <QDebug>
int main() {
QList<char> charList;
// charList.append('A'); // この行をコメントアウトすると、リストは空になる
// !!! 危険なコード例 (リストが空の場合) !!!
// if (!charList.isEmpty()) {
// char firstChar = charList.front();
// qDebug() << "最初の文字: " << firstChar;
// } else {
// // もしこのチェックを怠ると、下の行でクラッシュする可能性がある
// // char dangerChar = charList.front(); // これがクラッシュの原因になる!
// qDebug() << "リストは空です。front()を呼び出すと危険です!";
// }
// --- 常にisEmpty()で確認する安全な方法 ---
if (!charList.isEmpty()) {
char firstChar = charList.front();
qDebug() << "最初の文字: " << firstChar;
} else {
qDebug() << "リストが空のため、最初の文字にはアクセスできません。";
}
qDebug() << "--------------------";
// --- constなQListでの使用例 ---
QList<int> constList;
constList.append(100);
constList.append(200);
const QList<int>& readOnlyList = constList; // const参照でQListを受け取る
if (!readOnlyList.isEmpty()) {
// const QListに対するfront()は const T& を返す
const int& value = readOnlyList.front();
qDebug() << "読み取り専用リストの最初の要素: " << value;
// value = 50; // コンパイルエラー: const参照なので変更不可
} else {
qDebug() << "読み取り専用リストは空です。";
}
return 0;
}
解説
- const QListとの組み合わせ
const QList
オブジェクトに対してfront()
を呼び出すと、返される参照も自動的にconst T&
(const
参照)になります。これにより、その参照を通じてリストの要素を変更しようとすると、コンパイルエラーが発生し、安全性が保たれます。これは、特定の関数がリストの内容を変更しないことを保証したい場合に特に役立ちます。 - isEmpty()チェックの重要性
最初のブロックで示されているように、if (!charList.isEmpty())
によるチェックは必須です。これを怠ると、空のリストに対してfront()
を呼び出し、未定義の動作(通常はプログラムのクラッシュ)を引き起こします。
QList::front()
は、Qtでリストの最初の要素に効率的にアクセスし、必要に応じて変更するための非常に強力なツールです。しかし、その強力さゆえに、以下の点を常に念頭に置いて使用してください。
- 常に
isEmpty()
でリストが空でないことを確認する。 これが最も重要です。 front()
は参照を返すため、その参照を通じて要素の値を直接変更できることを理解する。意図しない変更を防ぐには、const
参照として受け取ることを検討する。const QList
オブジェクトに対してfront()
を使用した場合、返される参照もconst
になるため、要素を変更できないことを覚えておく。
front()
の主な目的は「リストの最初の要素への参照を得る」ことですが、この目的を達成するためのいくつかの異なるアプローチがあります。
QList::at(0) / QList::value(0)
これらは、インデックスを使って最初の要素にアクセスする最も一般的な方法です。
-
QList::value(int i)
:- 指定されたインデックス
i
にある要素のコピーを返します。 at()
と同様に、リストが空の場合やインデックスが範囲外の場合は未定義の動作になります。- 引数としてデフォルト値を指定できるオーバーロードがあり、これによりインデックスが範囲外の場合に安全なフォールバックを提供できます。
- 指定されたインデックス
-
QList::at(int i)
:- 指定されたインデックス
i
にある要素へのconst
参照を返します。 front()
と同様に、リストが空の場合やインデックスが範囲外の場合(この場合は0
)は未定義の動作を引き起こします。ただし、Qtのデバッグビルドでは通常、アサーション(assertion)がトリガーされ、問題が早く発見されます。const
参照を返すため、要素を変更することはできません。読み取り専用のアクセスに適しています。
- 指定されたインデックス
コード例
#include <QList>
#include <QDebug>
int main() {
QList<int> numbers;
numbers.append(10);
numbers.append(20);
// --- QList::at(0) ---
if (!numbers.isEmpty()) {
const int& firstValueAt = numbers.at(0); // const参照を返す
qDebug() << "at(0) で取得: " << firstValueAt; // 出力: at(0) で取得: 10
// numbers.at(0) = 5; // コンパイルエラー: at()はconst参照を返すため変更不可
} else {
qDebug() << "リストは空です (at(0)を使う場合)。";
}
// --- QList::value(0) ---
if (!numbers.isEmpty()) {
int firstValueValue = numbers.value(0); // 値のコピーを返す
qDebug() << "value(0) で取得: " << firstValueValue; // 出力: value(0) で取得: 10
firstValueValue = 5; // これはfirstValueValue自身の値を変更するだけで、元のリストには影響しない
qDebug() << "リストの最初の要素 (value(0)の後): " << numbers.front(); // 出力: リストの最初の要素 (value(0)の後): 10
} else {
qDebug() << "リストは空です (value(0)を使う場合)。";
}
// value(int i, const T& defaultValue) の安全な使用例
QList<QString> names;
// names.append("Alice"); // この行をコメントアウトすると、デフォルト値が使われる
QString firstNameSafe = names.value(0, "DefaultName"); // リストが空なら"DefaultName"が返る
qDebug() << "value(0, defaultValue) で取得: " << firstNameSafe;
// リストが空の場合: 出力: value(0, defaultValue) で取得: "DefaultName"
// リストに要素がある場合: 出力: value(0, defaultValue) で取得: "Alice" (例として)
return 0;
}
比較と使い分け
front()
は常に参照を返すため、読み取りも変更も可能です。- 要素のコピーで十分な場合、またはデフォルト値を指定して安全性を高めたい場合:
value(0)
が適しています。特に、リストが空かもしれない場合にクラッシュを防ぎたいなら、デフォルト値のオーバーロードが非常に便利です。 - 読み取り専用で、値の変更を避けたい場合:
at(0)
が最適です。const
参照を返すため、安全です。
QList::operator[](int i)
これはC++の配列アクセス演算子に似ており、インデックス0
を使って最初の要素にアクセスします。
const
バージョンと非const
バージョンがあり、非const
バージョンは要素の読み取りと変更の両方を許可します。front()
と同様に、リストが空の場合やインデックスが範囲外の場合(この場合は0
)は未定義の動作を引き起こします。QList<T>::operator[](int i)
は、指定されたインデックスi
にある要素への参照を返します。
コード例
#include <QList>
#include <QDebug>
int main() {
QList<double> temperatures;
temperatures.append(25.5);
temperatures.append(28.1);
// --- 読み取り ---
if (!temperatures.isEmpty()) {
double currentTemp = temperatures[0]; // 参照を取得し、値をコピー
qDebug() << "[] で取得: " << currentTemp; // 出力: [] で取得: 25.5
} else {
qDebug() << "リストは空です ([]を使う場合)。";
}
// --- 変更 ---
if (!temperatures.isEmpty()) {
temperatures[0] = 26.0; // 参照を通じて直接変更
qDebug() << "[] で変更後: " << temperatures[0]; // 出力: [] で変更後: 26
qDebug() << "変更後のリスト: " << temperatures; // 出力: 変更後のリスト: QList(26, 28.1)
}
return 0;
}
比較と使い分け
- どちらも空のリストに対するアクセスは未定義の動作となるため、
isEmpty()
チェックが必要です。 operator[]
は任意のインデックスにアクセスできる汎用性がありますが、front()
は「最初の要素」という特定の意味を強調します。front()
とoperator[]
は、機能的には非常に似ています。どちらも最初の要素への参照を返し、変更が可能です。
イテレータ (QList::begin())
イテレータを使用すると、より柔軟なリストの走査が可能になります。最初の要素にアクセスするためにも使えます。
QList
のイテレータには、QList::iterator
(読み書き可能)とQList::const_iterator
(読み取り専用)があります。- イテレータを逆参照(
*
演算子)することで、その要素への参照を得られます。 QList::begin()
は、リストの最初の要素を指すイテレータを返します。
コード例
#include <QList>
#include <QDebug>
int main() {
QList<QString> words;
words.append("Apple");
words.append("Banana");
// --- 非constイテレータで読み取りと変更 ---
if (!words.isEmpty()) {
QList<QString>::iterator it = words.begin();
qDebug() << "イテレータで取得 (変更前): " << *it; // 出力: イテレータで取得 (変更前): "Apple"
*it = "Orange"; // 参照を通じて要素を変更
qDebug() << "イテレータで変更後: " << *it; // 出力: イテレータで変更後: "Orange"
qDebug() << "リスト全体: " << words; // 出力: リスト全体: QList("Orange", "Banana")
} else {
qDebug() << "リストは空です (イテレータを使う場合)。";
}
qDebug() << "--------------------";
// --- constイテレータで読み取り専用アクセス ---
QList<int> scores;
scores.append(85);
scores.append(92);
// const QListに対してもbegin()はconst_iteratorを返す
QList<int>::const_iterator constIt = scores.begin();
if (constIt != scores.end()) { // begin()とend()が同じならリストは空
qDebug() << "constイテレータで取得: " << *constIt; // 出力: constイテレータで取得: 85
// *constIt = 90; // コンパイルエラー: constイテレータなので変更不可
} else {
qDebug() << "リストは空です (constイテレータを使う場合)。";
}
return 0;
}
比較と使い分け
begin()
とend()
を比較することで、リストが空かどうかを安全に判断できます(begin() == end()
なら空)。- 単に最初の要素にアクセスするだけであれば、
front()
やoperator[]
の方が簡潔です。 - イテレータは、最初の要素だけでなく、リスト全体を順次処理する際に非常に強力です。
QQueueやQStackの利用 (リストの先頭/末尾操作に特化する場合)
もしリストの先頭(または末尾)への追加と削除が主な操作であるなら、QList
よりもQQueue
やQStack
といった専用のコンテナを検討する方が適切かもしれません。
-
QStack
: 後入れ先出し(LIFO)のスタック構造を提供します。QStack::top()
: スタックの先頭要素への参照を返します。
-
QQueue
: 先入れ先出し(FIFO)のキュー構造を提供します。QQueue::head()
: キューの最初の要素への参照を返します。QList::front()
と非常に似ています。QQueue::dequeue()
: 最初の要素を取り除いて返します。
コード例 (QQueue)
#include <QQueue>
#include <QDebug>
int main() {
QQueue<QString> taskQueue;
taskQueue.enqueue("Task A"); // キューに追加
taskQueue.enqueue("Task B");
if (!taskQueue.isEmpty()) {
QString& currentTask = taskQueue.head(); // 最初のタスクへの参照を取得
qDebug() << "現在のタスク (参照): " << currentTask; // 出力: 現在のタスク (参照): "Task A"
currentTask = "Task A (Processed)"; // 参照を通じて変更
qDebug() << "変更後タスク: " << taskQueue.head(); // 出力: 変更後タスク: "Task A (Processed)"
} else {
qDebug() << "タスクキューは空です。";
}
if (!taskQueue.isEmpty()) {
QString completedTask = taskQueue.dequeue(); // 最初のタスクを取り出す
qDebug() << "完了したタスク: " << completedTask; // 出力: 完了したタスク: "Task A (Processed)"
qDebug() << "次のタスク: " << taskQueue.head(); // 出力: 次のタスク: "Task B"
}
return 0;
}
比較と使い分け
- リストの先頭要素への参照取得と同時に、その要素をリストから削除する操作を頻繁に行う場合は、
QQueue::dequeue()
のような関数が非常に便利です。 QList
が汎用的なリストであるのに対し、QQueue
やQStack
は特定のデータ構造(キュー、スタック)に特化しており、それらの操作(先頭/末尾へのアクセスや追加/削除)がより直感的で、効率的になる場合があります。
QList::front()
の代替手段は、それぞれ異なる特性と利点を持っています。
QQueue::head()
/QStack::top()
: リストの先頭/末尾操作に特化したコンテナを使うことで、コードの意図をより明確にし、特定の操作の効率を高めたい場合。- イテレータ (
QList::begin()
): リストを順次処理する際に最初の要素にアクセスする場合や、より細かい制御が必要な場合。 QList::operator[](0)
:front()
と非常に似ており、読み取りも変更も可能。汎用的なインデックスアクセスの一部として使いたい場合。QList::value(0)
: 読み取り専用で、リストが空かもしれない場合にデフォルト値を指定して安全性を高めたい場合。QList::at(0)
: 読み取り専用で、リストが空でないことが確実な場合。