Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在临时对象中传递成员的地址是有效的?_C++ - Fatal编程技术网

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

C++ 为什么在临时对象中传递成员的地址是有效的?,c++,C++,考虑以下代码 struct MyVARIANT { VARIANT var_; MyVARIANT(unsigned uVal) { VariantInit(&var_); var_.ulVal = uVal; var_.vt = VT_UI4; }; ~MyVARIANT() { VariantClear(&var_); } VARIANT* operator&

考虑以下代码

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调用
非常量变量*
。因此,当我试图从变量包装器传递
VARIANT*
时,我遇到了这个问题

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

但是当我重写
MyVARIANT::operator&
以传递内部成员的地址时,编译器在
bar()
中不会这样抱怨

两者的区别是什么

&MyVARIANT(1u).var_


? < p>这是合法的,因为C++只保护已知的危险结构。

&MyVariant(1).var
指针明确指向临时变量的成员


MyVariant(1)::另一方面,运算符(&()
正在调用用户定义的函数。编译器不会猜测该函数的实现;在给定的上下文中,这是一个合法的调用。

< P>这是合法的,因为C++只保护已知的风险结构。
&MyVariant(1).var
指针明确指向临时变量的成员


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

编译器不知道您在重载的
运算符&
中执行什么操作;您还可能返回无效指针。因此,当从临时对象访问我的
运算符&
时,它可能是UB?这里没有UB,在临时对象上调用成员函数是可以的。您可以像在其他任何地方一样在那里触发UB,但代码中没有问题(除了代码< >运算符和通常的怪异之外,考虑一个隐式转换或一个吸气剂)@VTT是的,你是对的。在尝试取消对返回的悬挂指针的引用之前,它不是UB。编译器不知道你在重载的
运算符&
中做什么;你也可能返回无效的指针。因此,当从临时对象访问我的
运算符&
时,它可能是UB?这里没有UB,在t上调用成员函数现在的对象很好。你可以在任何地方触发UB,但是在你的代码中没有问题(除了通常的怪异关于代码>运算符和<代码>之外,考虑一个隐式转换或者一个吸气剂)。@ VTT是的,你是对的。“C++只保护您不受已知风险结构的影响”这对我来说是新闻:)“C++只保护您不受已知风险结构的影响”这对我来说是新闻:)
&MyVARIANT(1u)
// same as MyVARIANT::operator& (&MyVARIANT(1u)) { return &this->var_; }