13.9 Overloading the subscript operator


https://www.learncpp.com/cpp-tutorial/overloading-the-subscript-operator/
arrayを処理する際、subscript演算子[]を使用して特定の要素を使用することがよくあります.
クライアントでオペレータ[]を使用する方法を見てみましょう

Overloading operator[]


下付きオペレータはmember関数で実現するべきです
[]で元のファイルにアクセスできるようにする必要がありますので、設定は参照として返されます.
class IntList
{
private:
    int m_list[10]{};

public:
    int& operator[] (int index);
};

int& IntList::operator[] (int index)
{
    return m_list[index];
}
前述のようにクラスを設定してmember関数を定義すると、
IntList list{};
list[2] = 3; // set a value
std::cout << list[2] << '\n'; // get a value

return 0;

Why operator[] returns a reference


考慮すると、[]演算子がアクセスするvalueをl-valueとして使用できます.
refにロードされていないとエラーが発生します(考えてみてください)
ちなみに、int&ではなくint&で符号化時にreturn値を設定するとcompilerがエラーを投げ出す

Dealing with const objects


const objectが[]演算子を使用している場合、どうすればいいですか?
c++では、constバージョンと非constバージョンを別々に定義できます.
#include <iostream>

class IntList
{
private:
    int m_list[10]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // give this class some initial state for this example

public:
    int& operator[] (int index);
    int operator[] (int index) const; // could also return const int& if returning a non-fundamental type
};

int& IntList::operator[] (int index) // for non-const objects: can be used for assignment
{
    return m_list[index];
}

int IntList::operator[] (int index) const // for const objects: can only be used for access
{
    return m_list[index];
}

int main()
{
    IntList list{};
    list[2] = 3; // okay: calls non-const version of operator[]
    std::cout << list[2] << '\n';

    const IntList clist{};
    clist[2] = 3; // compile error: calls const version of operator[], which returns a const reference.  Cannot assign to this.
    std::cout << clist[2] << '\n';

    return 0;
}

Error checking


次のエラーが発生した場合、どうすればいいですか?
int list[5]{};
list[7] = 3; // index 7 is out of bounds!
メンバー変数のサイズがわかり、エラーチェックが可能です
#include <cassert> // for assert()
#include <iterator> // for std::size()

class IntList
{
private:
    int m_list[10]{};

public:
    int& operator[] (int index);
};

int& IntList::operator[] (int index)
{
    assert(index >= 0 && index < std::size(m_list));

    return m_list[index];
}
assert()関数を使用して、条件が本当でない場合はエラーメッセージとともに終了できます.

The function parameter does not need to be an integer


そしてfunctionのパラメータは必ずしも整数ではありません
#include <iostream>
#include <string>

class Stupid
{
private:

public:
	void operator[] (const std::string& index);
};

// It doesn't make sense to overload operator[] to print something
// but it is the easiest way to show that the function parameter can be a non-integer
void Stupid::operator[] (const std::string& index)
{
	std::cout << index;
}

int main()
{
	Stupid stupid{};
	stupid["Hello, world!"];

	return 0;
}
以上のように、stringをインデックス出力とするオペレータのリロードも実現できる