为何取临时对象成员地址报错,重载&运算符则可行?
为什么两种取地址写法的编译结果不同?
咱们把问题拆开来,逐个分析两种写法的本质差异:
1. &MyVARIANT(1u).var_ 报错的核心原因
MyVARIANT(1u) 创建的是一个临时对象(属于右值范畴),它的生命周期只在当前表达式结束前有效。当你试图取它的成员 var_ 的地址时,MyVARIANT(1u).var_ 这个表达式本身是一个右值——C++标准明确规定,原生的 & 取地址运算符只能作用于左值或者函数指示符,右值是不允许被直接取地址的。这就是编译器抛出E0158错误的根本原因:你违反了语言对右值的操作限制。
2. &MyVARIANT(1u) 能正常编译的原因
这里的 & 并不是原生的取地址运算符,而是调用了你自定义的重载版 operator&():
- 临时对象(右值)可以调用无引用限定的成员函数(你的
operator&()没有加&或&&修饰),所以编译器会匹配到你定义的VARIANT* operator&()函数。 - 在这个重载函数内部,
this指针指向的是那个临时对象(虽然对象本身是右值,但this本身是左值指针),因此取&var_是完全合法的——var_是当前对象的成员,在临时对象的生命周期内(直到SetValue调用完成)都是有效的左值,自然可以被取地址。
额外小提示
如果你想更严谨地限制这个重载函数只能被右值调用,可以给它加上右值引用限定:
VARIANT* operator&() && { return &var_; }
不过在你的现有代码里,不加也能正常工作,因为C++默认允许右值调用无引用限定的成员函数。
内容的提问来源于stack exchange,提问作者Chen OT
相关产品推荐
相关产品推荐

