C++自定义类型未重载operator->时是否会调用内置实现?
关于自定义类
operator->实现的可移植性结论 - 不存在“内置
operator->自动等价于(*p).m”的隐式生成规则,认为只要实现了operator*就可以省略operator->重载的认知不符合C++标准要求。 - 专门为指针语义、迭代器语义的自定义类型重载
operator->不是冗余开发工作,省略该重载、或者用=default声明该运算符的写法,完全不具备跨编译器可移植性。
C++标准对类类型
operator->的行为有明确约束:该运算符不会根据已实现的operator*自动生成等价逻辑,要么由用户显式给出符合语义的实现,要么该运算符不存在/为删除状态,调用时会直接触发编译错误。
验证测试
我编写了最小测试程序验证该行为:
struct S { int m;}; struct P { auto& operator*() const { return s;} auto operator->() const = default; // 尝试使用默认生成的operator-> S s; }; int main() { P p; p->m; }
实测结果
在Debian 8.3.0-6版本g++环境下的编译表现:
- 保留
=default声明operator->时,代码无法通过编译 - 移除
=default片段、完全不声明operator->时,代码同样无法通过编译 - 只有手动实现
operator->、返回内部成员的地址(即注释中{ return &s; }的写法)时,代码才能正常编译运行
实操建议
- 不要为了省几行代码省略
operator->重载,也不要用=default声明该运算符,这类写法在当前及未来数年的主流编译器版本下都不具备可移植性。 - 模拟指针、迭代器语义的自定义类型,
operator->的标准实现就是返回内部持有对象的指针,实现逻辑简单固定,不会增加额外的维护成本。反而是取巧省略的写法,会因为不符合C++标准规则,带来无意义的编译报错问题。
内容的提问来源于stack exchange,提问作者learnedSloth
相关产品推荐
相关产品推荐

