13.10 Overloading the parenthesis operator
https://www.learncpp.com/cpp-tutorial/overloading-the-parenthesis-operator/
これまで見たリロード演算子はparameterを決定することができたが、
まだ決まっていません.たとえば、演算子==では、常に2つのパラメータのみが処理されます.
!Operatorの場合、パラメータは1つのみ処理されます
Parenthesis演算子()の場合、タイプと数を決定できます.
二つのことを常に覚えなければならない.
第一に、カッコ演算子は常にメンバー関数によって実装される必要があります.
第二に、オブジェクト向けでないC++では、()オペレータは通常関数を呼び出すために使用されます.
クラスでoperator()という名前の関数のみを呼び出す
次に例を示します
subscript演算子の場合は1次元配列ですが、今回は2次元配列の場合、既存のsubscript演算子では十分ではありません.
しかし()演算子については、私たちが望むパラメータを得ることができます.
そこで,二次元マトリクスに近づくには以下の方法を用いる.
現在実際に使用されているのは以下の通りです.
Operator()は、通常、通信を実装するために使用されます.
関数のようにクラスを使用する
通常の関数と比較して,関数の利点はクラスベースであるため,member変数では
データを格納可能
ここでは簡単な通信例です
しかし、acc objectのmember変数に値を格納して使用することがわかります.
これを見ると、normal関数でもstatic変数を使用できる理由を考えるかもしれません.しかしfunctionでは、instanceはグローバルに1つしか持てません.
したがって、静的変数は一度に1つしか使用できません.
ただしfunctorを使用すると、必要に応じて任意の数のinstanceを作成し、それぞれ分離した場合にobjectとmember変数を使用することができます.
これまで見たリロード演算子はparameterを決定することができたが、
まだ決まっていません.たとえば、演算子==では、常に2つのパラメータのみが処理されます.
!Operatorの場合、パラメータは1つのみ処理されます
Parenthesis演算子()の場合、タイプと数を決定できます.
二つのことを常に覚えなければならない.
第一に、カッコ演算子は常にメンバー関数によって実装される必要があります.
第二に、オブジェクト向けでないC++では、()オペレータは通常関数を呼び出すために使用されます.
クラスでoperator()という名前の関数のみを呼び出す
An example
次に例を示します
class Matrix
{
private:
double data[4][4]{};
};
dataの場合、4 x 4のマトリクスですsubscript演算子の場合は1次元配列ですが、今回は2次元配列の場合、既存のsubscript演算子では十分ではありません.
しかし()演算子については、私たちが望むパラメータを得ることができます.
そこで,二次元マトリクスに近づくには以下の方法を用いる.
#include <cassert> // for assert()
class Matrix
{
private:
double m_data[4][4]{};
public:
double& operator()(int row, int col);
double operator()(int row, int col) const; // for const objects
};
double& Matrix::operator()(int row, int col)
{
assert(col >= 0 && col < 4);
assert(row >= 0 && row < 4);
return m_data[row][col];
}
double Matrix::operator()(int row, int col) const
{
assert(col >= 0 && col < 4);
assert(row >= 0 && row < 4);
return m_data[row][col];
}
前述したように、演算子()を定義して2つのintパラメータを受け入れる現在実際に使用されているのは以下の通りです.
#include <iostream>
int main()
{
Matrix matrix;
matrix(1, 2) = 4.5;
std::cout << matrix(1, 2) << '\n';
return 0;
}
parameterは一切受け付けなくてもご利用いただけます#include <iostream>
int main()
{
Matrix matrix{};
matrix(1, 2) = 4.5;
matrix(); // erase matrix
std::cout << matrix(1, 2) << '\n';
return 0;
}
Having fun with functors
Operator()は、通常、通信を実装するために使用されます.
関数のようにクラスを使用する
通常の関数と比較して,関数の利点はクラスベースであるため,member変数では
データを格納可能
ここでは簡単な通信例です
#include <iostream>
class Accumulator
{
private:
int m_counter{ 0 };
public:
int operator() (int i) { return (m_counter += i); }
};
int main()
{
Accumulator acc{};
std::cout << acc(10) << '\n'; // prints 10
std::cout << acc(20) << '\n'; // prints 30
return 0;
}
上のコードからaccというobjectを使うと関数のように見えますしかし、acc objectのmember変数に値を格納して使用することがわかります.
これを見ると、normal関数でもstatic変数を使用できる理由を考えるかもしれません.しかしfunctionでは、instanceはグローバルに1つしか持てません.
したがって、静的変数は一度に1つしか使用できません.
ただしfunctorを使用すると、必要に応じて任意の数のinstanceを作成し、それぞれ分離した場合にobjectとmember変数を使用することができます.
Reference
この問題について(13.10 Overloading the parenthesis operator), 我々は、より多くの情報をここで見つけました https://velog.io/@ikmy0ung/13.10-Overloading-the-parenthesis-operatorテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol