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