2009-11-27 3 views
8

У меня возникли проблемы с использованием условного оператора для получения ссылки на объект. У меня есть установка похожа на это:Условный оператор issue

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;  
} 

При компиляции, это дает мне следующую ошибку:

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()' 

Я понимаю, что это незаконно согласно C стандартный ++ (as seen in this blog post), но я не Не знаю, как получить мою ссылку на D без использования условного оператора.

Любые идеи?

ответ

14

Cast к D& в обеих ветвях:

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

Да, это работает отлично. – laura

+1

Вам также нужен только один из приведений, что делает выражение немного менее подробным. –

+0

@ Рихард, а хорошая записка. Для меня это выглядит проще, если я применяю приведение к обоим операндам, но вы, конечно, правы, один из них достаточно, чтобы компилятор мог видеть, что другой может быть преобразован в 'D &' неявно. –

2

Btw, вам не нужно использовать условный оператор,

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

будет работать тоже.

+0

Это выглядит немного расточительно. Есть ли положительный эффект на этот подход, стих оператора Ternary? –

+0

Это правда, но я считаю, что код выглядит неуклюжим, если вы это сделаете (используя ссылку выглядит чище). – laura

+1

Стивен, я только предоставлял ответ в ответ на OP «но я не знаю, как получить ссылку на D без использования тройного оператора» –

0

Или вы можете изменить возвращаемые типы функций базовому классу.

+0

Это переработает остальную часть кода, используя два геттера с динамическими нажатиями, это не совсем решение. – laura

+0

вы правы, static_cast должен работать. – shyam

Смежные вопросы