1

ここにnoob。以下は、本の例で出くわしたクラス定義の断片です。

double& operator[](int i);
double operator[](int i) const;

私の質問は、なぜこれが曖昧ではないのかということです。プロジェクトのファイルをコンパイルするとき、コンパイラはエラーを出しません。また、次のようになります(たとえば、AnyClassにvalarray<double>オブジェクトが含まれていて、直接アクセスしたいとします)。

AnyClass test;
cout << test[2]

コンパイラはどのバージョンを使用しますか?

4

4 に答える 4

7

constは署名の一部であり、過負荷の解決に使用できるため、あいまいではありません。したがってoperator[]、非constオブジェクトで使用する場合、それがconst最も具体的なオブジェクトであるため、オーバーロードを選択します。また、constオブジェクトで使用する場合は、それがconst適用される唯一のオブジェクトであるため、オーバーロードを選択します。

于 2012-09-04T16:10:44.067 に答える
1

constオブジェクトで呼び出された場合はconstバージョンが使用され、それ以外の場合は他のバージョンが使用されます。

これが、コンパイラがあいまいさを解決する方法です。

于 2012-09-04T16:10:09.697 に答える
1
AnyClass test;
const AnyClass const_test;
std::cout << test[2];       // calls operator[](int)
std::cout << const_test[2]; // calls operator[](int) const
于 2012-09-04T16:10:47.597 に答える
1

これを理解するには、ほとんどの場合const、引数のaが呼び出しの曖昧さを解消するのに十分であることを理解する必要があります。

#include <iostream>

void foo(char* ptr)
{
    std::cout << "mutable: " << ptr << std::endl;
}

void foo(const char* ptr)
{
    std::cout << "const: " << ptr << std::endl;
}

int main()
{
    const char* constHello = "hello";
    char mutableHello[] = "hello";
    foo(constHello);
    foo(mutableHello);
}

これは印刷します:

const:hello
mutable:hello

コンパイラーは、可能な限り制限の少ないオーバーロードを選択します。したがって、過負荷があるchar*ときにを使用するchar*と、それが選択されます。しかし、存在しない場合、コンパイラーはそれをaにキャストすることがconst char*実行可能な変換であると判断します(逆は明らかに真実ではありません)。

さて、非常に単純なことは、すべてのメソッドがthis関数の最初のパラメーターとしてポインターを渡すことです。このパラメーターは、簡単にするために非表示になっています。メソッドのconst最後にあるは、引数を修飾しthisます。これまで見てきたようconstに、ポインタ上のaはオーバーロードを明確にするのに十分なので、これは効果的に機能します。

于 2012-09-04T16:16:58.723 に答える