【问题标题】:Conditional operator issue条件运算符问题
【发布时间】:2010-12-20 22:05:39
【问题描述】:

我在使用条件运算符获取对象引用时遇到了一些麻烦。我有类似这样的设置:

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 的引用。

有什么想法吗?

【问题讨论】:

    标签: c++ conditional-operator


    【解决方案1】:

    在两个分支中转换为D&

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

    【讨论】:

    • 这里也只需要一个演员表,这使得表达式不那么冗长。
    • @Richard,好记。对我来说,如果我将强制转换应用于两个操作数,看起来会更容易,但你当然是对的,一个强制转换足以让编译器看到另一个可以隐式转换为 D&amp;
    【解决方案2】:

    顺便说一句,你真的不需要使用条件运算符,

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

    也可以。

    【讨论】:

    • 这看起来有点浪费。与三元运算符相比,这种方法有什么好处吗?
    • 这是对的,但如果你这样做,我发现代码看起来很笨拙(使用参考看起来更干净)。
    • 斯蒂芬,我只是为回应 OP 的“但我不知道如何在不使用三元运算符的情况下获得对 D 的引用”而提供答案
    • 我怀疑这属于“个人偏好”类别:我确实觉得它不那么笨重,特别是因为在这种情况下,普通的 (D&amp;)-cast 就足够了(转换为基类)所以三元运算符是完全可读的,您没有额外的变量,稍后将不使用。我不确定演员是否有资格作为 RTTI 使用。但是,您的回答完全有效,我不明白为什么它被否决了。
    【解决方案3】:

    或者您可以将函数的返回类型更改为基类。

    【讨论】:

    • 这将使用带有动态转换的两个 getter 来填充其余代码,这不是真正的解决方案
    猜你喜欢
    • 2015-05-20
    • 2011-08-13
    • 2011-02-21
    • 2013-06-20
    • 1970-01-01
    • 2013-11-01
    • 1970-01-01
    • 2010-09-22
    • 2011-06-13
    相关资源
    最近更新 更多