__declspec(property)与operator[]结合使用的异常问题咨询
问题原因分析
这个差异是微软__declspec(property)扩展的特殊行为导致的,具体细节如下:
直接调用
get_a()的正常逻辑
执行(b.get_a())[0][12][19]时,代码会按预期顺序执行:- 先调用
get_a()返回*a的副本(临时A对象) - 对该临时对象调用
operator[](0),输出0并返回对象副本 - 对新的临时对象调用
operator[](12),输出12并返回副本 - 最后调用
operator[](19),输出19
整个链式调用会依次触发每个operator[],因此输出三个数字。
- 先调用
__declspec(property)的异常解析逻辑
微软的__declspec(property)在处理属性的链式下标操作时,存在非标准的解析行为:
当你写(b.a_test)[0][12][19]时,编译器没有按普通链式调用处理,而是错误地将整个表达式绑定到属性本身,最终仅触发最后一个operator[](19)的调用,前面的[0]和[12]对应的operator[]被直接忽略,因此只输出19。本质是编译器对属性的下标操作做了特殊绑定,没有依次对每个
operator[]的返回值应用后续下标,跳过了前面的下标操作步骤。修复方案
要让属性的链式下标操作正常工作,可修改两处代码:- 让
get_a()返回引用而非值:A& get_a() { return *a; } - 让
A的operator[]返回引用而非值:A& operator[](int i) { std::cout << i << "\n"; return *this; }
这样属性访问返回左值,编译器会按正常链式调用逻辑处理每个
operator[]。- 让
内容的提问来源于stack exchange,提问作者Eliott Martin
相关产品推荐
相关产品推荐

