2012-01-24 9 views
4

B(const B&)の代わりにB(B&) ctorが呼び出されたのはなぜですか?オブジェクトb1の構成では、以下のコードで最初のコピーコンストラクタが呼び出されるのはなぜですか?

#include <iostream> 
using namespace std; 

struct B 
{ 
    int i; 
    B() : i(2) { } 
    B(B& x) : i(x.i) { cout << "Copy constructor B(B&), i = " << i << endl; } 
    B(const B& x) : i(x.i) { cout << "Copy constructor B(const B&), i = " << i << endl; } 
}; 

int main() 
{ 
    B b; 
    B b1(b); 
} 
+1

bはconstではないためですか? –

答えて

2

13.3.3.2/3は

二つの暗黙的な変換を語ります同じ形式の配列は、以下の規則のうちの1つが適用されない限り、区別できない変換配列である:

- 標準変換シーケンスS1は、標準的な変換シーケンス S2よりも良好な変換シーケンスである場合:

S1及びS2は、参照が同じ 型で参照する参照バインディング(8.5.3)、およびタイプでありますトップレベルのcv修飾子を除いて、S2によって初期化された参照が参照する型は、S1によって初期化された参照が参照する型よりも多く、 である。 [例:引数が非constであるので、それはより良い試合ですので、あなたの場合は

int f(const int &); 
int f(int &); 
... 
int i; 
int j = f(i); // calls f(int&) 

、コピーC-TORの非constバージョンが選択されています。

+0

偉大な答え。おめでとう! – Ayrosa

5

bはconstではないためです。したがって、最初のコピーctorと完全に一致するので、コンパイラが使用します。オーバーロードの解決が適用されるため

+0

参考にしていただけますか? – Belloc

6

はこれがある、とb1のコンストラクタの引数はbで、bは非const左辺値であることを起こることから、その後、非const lvlalueを取るコンストラクタが選択されています。それが最初のものです。興味深いことに、どちらもコピーコンストラクタですが、後者のコードではコードは等しくなります。

+0

参考資料はありますか? – Belloc

+1

ISO/IEC 14882の全節12.8は、コピーコンストラクタに関するものです。あなたが興味を持っている何か興味がありますか? オーバーロードが行われる限り、それは第13章全体です。そしてそれはかなり複雑です。 – bronekk

+0

...さらに、過負荷解決に関連する括弧の束...あなたは心配していますか? –

1

bは定数ではないためです。

1

これを試してみてください:

int main() { 
    const B b; 
    B b1(b); 
} 

また、それはあなたがconstのかを使用する必要がありますwheter難しい決断だ;)

関連する問題