C++中基类auto返回函数能否根据调用者返回对应类型指针?
实现基类函数根据调用者类型返回对应指针类型
你的需求可以实现,但直接用auto推导返回值行不通——基类中auto changer()的返回值在编译基类时就被固定为Super*,子类调用该函数时返回的仍然是Super*,赋值给Sub*会触发类型不匹配的编译错误。
要让函数根据调用者类型返回对应指针,最常用的方案是CRTP(奇异递归模板模式),通过模板将子类类型传递给基类,让基类能返回子类的指针类型。具体实现如下:
template<typename Derived> class Super { public: int x; Super() : x(0) {} ~Super() = default; // 返回子类Derived的指针 Derived* changer() { x += 10; // 安全的静态转换,因为Derived继承自Super<Derived> return static_cast<Derived*>(this); } // 可选的常量版本 const Derived* changer() const { return static_cast<const Derived*>(this); } }; // 子类继承时传入自身作为模板参数 class Sub : public Super<Sub> {}; int main() { Sub* sub = new Sub(); Sub* sub2 = sub->changer(); // 编译通过,返回Sub* // 基类自身使用示例 Super<Super<int>>* base = new Super<Super<int>>(); Super<Super<int>>* base2 = base->changer(); // 返回Super<Super<int>>* }
原理说明
CRTP通过将子类类型作为模板参数传递给基类,让基类在编译期就能确定返回的指针类型。static_cast在这里是安全的,因为我们明确知道当前对象的实际类型是Derived(子类继承自Super<Derived>),不会出现类型转换错误。
其他方案的局限性
如果尝试用虚函数的返回类型协变,你必须在子类中重写changer函数,无法做到基类实现一次、子类直接复用的效果,因此CRTP是更符合你需求的方案。
内容的提问来源于stack exchange,提问作者s_question
相关产品推荐
相关产品推荐

