2011-09-02 14 views
19

Qtの共有データポインタに似たものを私の目的のためにラップしようとしましたが、テストの結果、const関数を呼び出す必要があるとき、代わりに選ばれた。非constバージョンではなくconst関数を呼び出す

私はC++ 0xのオプションでコンパイルすると、ここに最小限のコードですよ:あなたが見ることができるように

struct Data { 
    int x() const { 
     return 1; 
    } 
}; 

template <class T> 
struct container 
{ 
    container() { 
     ptr = new T(); 
    } 


    T & operator*() { 
     puts("non const data ptr"); 
     return *ptr; 
    } 

    T * operator->() { 
     puts("non const data ptr"); 
     return ptr; 
    } 

    const T & operator*() const { 
     puts("const data ptr"); 
     return *ptr; 
    } 

    const T * operator->() const { 
     puts("const data ptr"); 
     return ptr; 
    } 

    T* ptr; 
}; 

typedef container<Data> testType; 

void testing() { 
    testType test; 
    test->x(); 
} 

、Data.xはconstの関数であるので、オペレータ - >と呼ばれはする必要がありますコンスタント。非constのものをコメントアウトすると、エラーなしでコンパイルされるので、可能です。しかし、私の端末版画:

"非constのデータPTR"

それはGCCのバグ(私は4.5.2を持っている)か、それとも私が欠けている何かがあるのでしょうか?

答えて

17

constのみが異なる2つのオーバーロードがある場合、コンパイラは*thisconstかどうかに基づいてコールを解決します。あなたのコード例では、testconstではないので、constオーバーロードが呼び出されます。

あなたはこれをしなかった場合:

testType test; 
const testType &test2 = test; 
test2->x(); 

test2constあるので、あなたは、他の過負荷が呼び出されることを確認する必要があります。

+2

したがって、constオーバーロードを呼び出すことができたとしても、オブジェクトがconst宣言されていない場合、コンパイラは非constオーバーロードを呼び出すことを好みますか? – coyotte508

+2

@ coyotte508:正確に。 nonconst'オーバーロードはより良い一致とみなされます。 –

1

ただし、testTypeはconstオブジェクトではありません。

したがって、メンバの非constバージョンを呼び出します。
メソッドのパラメータがまったく同じ場合は、呼び出すバージョンを選択する必要があります(したがって、thisパラメータ(非表示のもの)を使用します)。この場合、これはconstではないので、非constメソッドを取得します。

testType const test2; 
test2->x(); // This will call the const version 

これは、非constオブジェクトでconstメソッドを呼び出すことができるので、x()への呼び出しには影響しません。

2

Data::xが定数機能であるかどうかは関係ありません。呼び出された演算子は​​クラスに属し、Dataクラスではなく、そのインスタンスは定数ではないため、定数でない演算子が呼び出されます。利用可能な定数演算子しかない場合、またはクラスのインスタンス自体が定数であった場合、定数演算子が呼び出されます。

4

testはconstオブジェクトではないため、コンパイラは最適な一致を検出します。非constバージョン。 static_cast<const testType&>(test)->x();

EDIT:あなたはしかしstatic_castでconst性を適用することができ、あなたが考える時間の99.9%を疑われるようさておき、あなたはいくつかの奇妙な癖と、コンパイラはおそらくありますよう、あなたのコードを再検討すべきコンパイラのバグを発見してきたように実際には標準に従っています。

+0

"あなたはおそらくコンパイラのバグを見つけられていません"のコメント – MikMik

関連する問題