为什么在临时对象中传递成员的地址是有效的?

时间:2018-05-24 08:21:43

标签: c++

考虑以下代码。

struct MyVARIANT
{
    VARIANT var_;

    MyVARIANT(unsigned uVal) {
        VariantInit(&var_);
        var_.ulVal = uVal;
        var_.vt = VT_UI4;
    };

    ~MyVARIANT() {
        VariantClear(&var_);
    }

    VARIANT* operator&() {
        return &var_;
    }
};    

HRESULT SetValue(VARIANT* val)
{
    return S_OK;
}


void foo()
{
    SetValue(&MyVARIANT(1u).var_);
    // E0158    expression must be an lvalue or a function designator
}

void bar()
{
    SetValue(&MyVARIANT(1u));
    // Fine
}

需要许多WIN32 API调用non-const VARIANT*作为参数类型。所以当我尝试从我的VARIANT包装器中传递VARIANT*时,我遇到了这个问题。

编译器抱怨foo(),因为我通过operator &传递临时对象的数据成员的地址,这不是l值。

但是当我覆盖MyVARIANT::operator&以传递内部成员的地址时,编译器不会在bar()中以这种方式抱怨。

之间有什么区别
&MyVARIANT(1u).var_

&MyVARIANT(1u)
// same as MyVARIANT::operator& (&MyVARIANT(1u)) { return &this->var_; }

1 个答案:

答案 0 :(得分:2)

这是合法的,因为C ++只保护您免受已知风险构造的影响。 &MyVariant(1).var指针肯定指向临时成员。

另一方面,

MyVariant(1)::operator&()调用用户定义的函数。编译器不会猜测该函数的实现;在给定的背景下,这是一个合法的电话。