2011-01-16 19 views
8

対非const参照VS const参照は暗黙的な変換:非参照

struct A {}; 
struct B { B(const A&) {} }; 
void f(B) 
{ 
    cout << "f()"<<endl; 
} 
void g(A &a) 
{ 
    cout << "g()" <<endl; 
    f(a); //a is implicitly converted into B. 
} 
int main() 
{ 
    A a; 
    g(a); 
} 

これcompiles fineは、正常に動作、このコードを考えてみましょう。しかし、f(B)f(B&)に変更すると、doesn't compileとなります。もし私がf(const B&)と書いたら、もう一度compiles fine、うまく動作します。理由と合理性はなぜですか?

概要:

void f(B);   //okay 
void f(B&);  //error 
void f(const B&); //okay 

Iは、これらの場合のそれぞれについて、言語仕様から理由、根拠と基準(複数可)を聞きたいです。もちろん、関数のシグネチャ自体は間違っているわけではありません。むしろABconst B&に暗黙的に変換されますが、B&には変換されず、コンパイルエラーが発生します。

答えて

7

、根拠及び参照(s)は言語仕様から

十分なC++の設計と進化ですか?

私は私によって非左辺値[コメントによって初期化されるように非const参照を可能にすることにより、しかし、1つの重大なミスを犯した。その文言が不正確です!]。たとえば:のでint&はそう、一時渡さdoubleを参照することができないタイプの違いの

void incr(int& rr) { ++rr; } 

void g() 
{ 
    double ss = 1; 
    incr(ss); // note: double passed, int expected 
       // (fixed: error in release 2.0) 
} 

ssの値で初期化さ intを保持するために生成されました。したがって、 incr()は一時的に変更され、 の結果は呼び出し元関数 [ 強調の]に反映されませんでした。

それについて考える:参照による呼び出しの全体のポイントは、クライアントが関数によって変更されたものを渡し、関数が戻った後、クライアントが変更を観察することができなければならないということです。

+0

興味深いこと:ARMでは、一次式の有効性の決定は次のようになります。「結果が識別子の場合は左辺値です。」 msgstr "メンバーがメンバーの場合、結果は左辺値です。"私は、それはあまりにも意味があるはずですが、それはあまりにも "左辺値はオブジェクトや関数を参照する表現です"と定義しているのだろうかと疑問に思っています。うーん、多分それは単に "結果が左辺値であるということは、それがオブジェクトまたは関数を参照する場合です"という意味ですか? –

+0

これは良いことです。なぜそれが許されないのか理由を説明するので、私の質問によく答えると思う。私はこれを私の質問に対する答えとして受け入れています。 :-) – Nawaz

4

問題は、aからBオブジェクトへの暗黙的な変換がrvalueを生成することです。非const参照は、lvaluesにのみバインドできます。

Bがデフォルトのコンストラクタを持っていた場合、f(a)の呼び出しをf(B())に変更した場合と同じ動作になります。どのように標準を参照して説明するために

からStack Overflow - often used seldom defined terms: lvalue

GotW #88: A Candidate For the “Most Important const”

Stack Overflow - How come a non-const reference cannot bind to a temporary object?

: -

litbは左辺値であるものに偉大な答えを提供しますそれらの関数呼び出しが失敗するか、成功するかが過度に長くなります。重要なことはB& b = a;が失敗し、const B& b = a;が失敗しないことです。 [左辺値であり、いずれかの基準である -
は:

基準(ドラフトn1905から)次のようにタイプ「CV2のT2」の式で初期化され、「CV1のT1」とタイプします互換性のある、または暗黙的に参照互換性のある型の左辺値に変換することができます。
- それ以外の場合、参照は不揮発性のconst型(つまり、cv1はconstでなければなりません)になります。

Here's何かが参照互換型の左辺値に変換可能な場合。

私はその理由を聞きたい
+0

なぜ@ Nawazの質問は23分間返答されていませんでした。なぜなら、私はそれに答えたとき、あなたは私の前に30秒の答えを返しました。それは魔法です!ハハ、+1。 –

+0

@Chris:関連する言葉も引用してください。私は関連する概念を自分で探求できます。 – Nawaz

+3

厳密に言えば、値カテゴリは*オブジェクト*(実行時)ではなく*式*(コンパイル時)の属性であるため、左辺値または右辺値は作成できません。 – fredoverflow

関連する問題