代码之家  ›  专栏  ›  技术社区  ›  Chen OT

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

c++
  •  0
  • Chen OT  · 技术社区  · 6 年前

    考虑以下代码。

    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* 从我的变体包装器。

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

    但当我超越 MyVARIANT::operator& 为了传递内部成员的地址,编译器不会在 bar() .

    两者有什么区别

    &MyVARIANT(1u).var_
    

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

    ?

    1 回复  |  直到 6 年前
        1
  •  2
  •   MSalters    6 年前

    这是合法的,因为C++只保护已知的风险结构。这个 &MyVariant(1).var 指针绝对指向临时的成员。

    MyVariant(1)::operator&() 另一方面是调用用户定义的函数。编译器不会猜测该函数的实现;它是给定上下文中的合法调用。