views:

306

answers:

3

I'm having some trouble with using the conditional operator to get a reference to an object. I have the a setup similar to this:

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

When compiling, this gives me the following error:

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

I understand this is illegal according to the C++ standard (as seen in this blog post), but I don't know how to get my reference to D without using the conditional operator.

Any ideas?

+11  A: 

Cast to D& within both branches:

D& d = (rand() %2 == 0 ? static_cast<D&>(c.getD1()) : static_cast<D&>(c.getD2()));
Johannes Schaub - litb
Yep, this works perfectly.
laura
You only need one of the casts here too, which makes the expression a little less verbose.
Richard Corden
Johannes Schaub - litb
+2  A: 

Btw, you don't really need to use a conditional operator,

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

would work too.

Murali VP
This looks to be a little wasteful. Is there a benifit to this approach verses the Ternary operator?
Stephen Edmonds
This is true, but I find the code looks clunky if you do this (using the reference looks cleaner).
laura
Stephen, I was only providing an answer in response to OP's "but I don't know how to get my reference to D without using the ternary operator"
Murali VP
laura
A: 

Or you can change the return types of the functions to Base Class.

shyam
This would pepper the rest of the code using the two getters with dynamic casts, it's not really a solution
laura
you are right, static_cast should work.
shyam