2012-10-03 9 views
11

同じパラメータリストを使用して演算子を2回オーバーロードします。C++のオーバーロード演算子を2回、非const参照を1つ戻し、その他のconst参照は、どのような設定ですか?

T& operator()(par_list){blablabla}  
const T& operator()(par_list){blablabla} 

私は()演算子を呼び出すときに、どの関数がどのような嗜好や状況に基づいて呼び出されるのでしょうか? const関数の下でcall()を呼び出すと、const T &が必要です。

私は、C++がそのような状況をどのように処理し、どのようにデフォルト設定が動作するのか不思議です。

ありがとう

+1

用語がある*過負荷*、なし。 – chris

+2

C++戻り値の型によるオーバーロードを禁止します。人はそれができる/できないことに入ることができますが、それは問題ではありません。 1つのトリックは、戻り値の型がconstのときにメソッドをconstにすることです。オーバーロードする可能性があります。私の記憶はconstメソッドが優先され、非constはconst呼び出しが正当でないと呼ばれます。 – Joe

答えて

21

これらの関数は互いにオーバーロードされません。彼らは同じ署名を持っているので、同じ関数を再定義しようとする試みは誤りである。戻り値の型は関数の署名の一部ではありません。関数のオーバーロードを行うには、同じ名前で異なるパラメータまたはconst/volatileの修飾子を宣言する必要があります。つまり、戻り値の型ではなく、関数の修飾子です。

(どちらもオーバーライドしません。オーバーライドは、派生したクラスが基本クラスの仮想関数に対して行うものです)。

メンバ関数のオーバーロードをconstと定義し、非constとするのが一般的です。

T& operator()(par_list){blablabla} 
const T& operator()(par_list) const {blablabla} 
           ^^^^^ 

あなたは非constオブジェクトに()を適用した場合に呼び出される最初の、そしてconstオブジェクト上の第二:constオーバーロードだけではなく戻り値の型、機能constを宣言しなければなりません。例:

+0

@DavidRodríguez-dribeas:OK、私は "署名"が返されるタイプを認識しませんでした。 「どの過負荷を選ぶかを決定するビット」の正式な用語はありますか? –

+0

@DavidRodríguez-dribeasおそらく、C++ 03以降に変更されたように思われるので、これを明確にすることができます。 '§1.3.18'はテンプレート関数を参照しているようです。しかし、非テンプレート(フリーまたはメンバ)関数のエントリは戻り値には言及しません。テンプレート関数の特殊化のエントリもありません。 – juanchopanza

+0

@juanchopanza:あなたは正しいです、コメントを削除します。マイクは、標準を注意深く読んで、関数テンプレート(Juanchoの言及のように)が戻り値の型が署名の一部であることを示しています。正規関数の場合、署名には戻り値の型は含まれません。 C++ 03には脚注があります:*関数シグネチャには、オーバーロード解決に参加しないため、戻り値の型は含まれません。*答えに混乱を招いて申し訳ありません:) –

3

戻り値の型に基づいて関数/メソッドをオーバーロードすることはできません。私はコンパイラがここでエラーを投げると期待します。あなたにできることは

const T& operator()(par_list) const {blahblah} 

だけでなく、これはconst受信機で呼び出すことができます意味const修飾子を使用して、const法などの方法自体を指定しているが、それはまた、オーバーロードの解決に使用されています。これは、メソッドに渡される暗黙の*thisパラメータに影響するためです。 constメソッドは*thisconst修飾子を使用し、オーバーロード解決時にはconst修飾子が考慮されます。

1

オペレータを定義する方法は、コンパイラがどのoperator()を呼び出すか決めることはできません。関数(と演算子)のオーバーロードは、引数の型に対してのみ行うことができ、戻り型では実行できません。そして、実際には、同じ関数/演算子を再定義することを考慮して、コンパイラが2番目のものを定義するとすぐにコンパイル時にエラーが発生します。

しかし、次は(あなたが持っているものだろうと)共通です:

T& operator()(par_list){blablabla} 
const T& operator()(par_list) const {blablabla} 

あなたは非静的メンバ関数とメンバ関数は、暗黙的に持っている定義されているので、引数リストの後にこの追加の「CONST」が存在します隠し引数:クラスのインスタンスへの "this"ポインタ。この "const"キーワードは、この非表示ポインタがconstインスタンスかどうかを示します。この引数はオーバーロードの解決に関与します。この場合、コンパイラは使用する演算子のバージョンを選択するために使用します。

だから:

class A { 
    T& operator()() { ... } 
    const T& operator()() const { .... } 
}; 

A a; 
const A& ca(a); 
a(); -> returns a T& 
ca(); -> returns a const T& 
関連する問題