2009-11-27 29 views
8

条件演算子を使用してオブジェクトへの参照を取得する際に問題が発生します。私は、これはC++標準(as seen in this blog post)による違法であることを理解条件付き演算子の問題

WOpenTest.cpp: In function 'int 
main()': WOpenTest.cpp:91: error: no 
match for conditional 'operator?:' in 
'((((unsigned int)rand()) & 1u) == 0u) 
? c.C::getD1() : c.C::getD2()' 

が、私はドン:コンパイルするときに、これは私に次のエラーを与える

class D 
{ 
    virtual void bla() = 0; 
}; 

class D1 : public D 
{ 
    void bla() {}; 
}; 

class D2 : public D 
{ 
    void bla() {}; 
}; 

class C 
{ 
public: 
    C() 
    { 
     this->d1 = new D1(); 
     this->d2 = new D2(); 
    } 

    D1& getD1() {return *d1;}; 
    D2& getD2() {return *d2;} 
private: 
    D1 *d1; 
    D2 *d2; 
}; 

int main() 
{  
    C c;  
    D& d = (rand() %2 == 0 ? c.getD1() : c.getD2());  
    return 0;  
} 

:私はこれまで同様に設定して条件付き演算子を使用せずにDへの参照を取得する方法を知っていません。

アイデア?両方のブランチ内D&

答えて

14

キャスト:ところで、あなたは本当に条件演算子を使用する必要はありません

D& d = (rand() %2 == 0 ? static_cast<D&>(c.getD1()) : static_cast<D&>(c.getD2())); 
+0

これは完全に機能します。 – laura

+1

ここでもキャストの1つだけが必要です。これにより、表現が少し冗長になります。 –

+0

@リチャード、ああ、良いメモ。私には、両方のオペランドにキャストを適用すればもっと簡単に見えますが、もちろん正しいですが、コンパイラが暗黙的に 'D&'に変換できることをコンパイラに見せてもらえれば十分です。 –

2

D* dptr; if(rand() %2 == 0) dptr = &c.getD1(); else dptr = &c.getD2(); 
D& d = *dptr; 

があまりにも動作します。

+0

これはちょっと無駄です。このアプローチのベネフィットは三項演算子であるか? –

+0

これは当てはまりますが、あなたがこれを行うとコードが荒く見えることがわかります。 – laura

+1

スティーブン、私はOPの回答に対して答えを提供するだけだったが、三項演算子を使わずにDへの参照を得る方法がわからない " –

0

また、関数の戻り値の型を基本クラスに変更することもできます。

+0

これは、動的キャストを使用する2つのゲッターを使用してコードの残りの部分を処理します。実際には解決策ではありません。 – laura

+0

あなたは正しいです、static_castは動作するはずです。 – shyam