C++11中使用decltype推导返回类型的尾置虚函数如何声明签名?
解答
现有写法合法性
你给出的Int类中sum方法的写法完全符合C11标准,合法性仅依赖一个前提:你已经为Int类型实现了对应的operator+重载,确保*this + *v是合法表达式。
C11原生支持尾置返回类型语法,搭配decltype可以正确推导表达式的返回值类型,无需更高版本的标准支持。
基类声明虚版本的实现方案
你当前的写法无法直接在基类定义对应的虚函数,核心原因是:
C++的虚函数签名是编译期静态确定的,所有派生类重写虚函数时,签名必须和基类完全一致,仅允许协变返回类型的有限差异(基类返回基类指针/引用,派生类返回派生类指针/引用)。你用decltype(*this + *v)推导的返回类型和当前派生类强绑定,不同派生类的sum返回类型完全不同,基类无法定义统一的静态返回类型。
C++11兼容的可行实现方案如下:
方案1:类型擦除实现多态接口
如果需要运行时多态特性,将返回值和参数都做类型擦除,基类定义统一的虚接口:
struct abstract_object { virtual abstract_object* sum(abstract_object* v) = 0; virtual ~abstract_object() = default; // 必须定义虚析构函数避免内存泄漏 };
派生类重写时利用协变返回类型规则,内部做类型校验转换:
struct Int : public abstract_object { Int operator+(const Int& other) const { // 你的加法实现逻辑 } Int* sum(abstract_object* v) override { Int* other = dynamic_cast<Int*>(v); if (!other) { // 类型不匹配的错误处理逻辑 return nullptr; } return new Int(*this + *other); } };
如果担心原始指针的内存管理问题,可以将返回值替换为std::unique_ptr<abstract_object>,C++11已支持该智能指针。
方案2:放弃多态,直接派生类实现
如果你不需要运行时多态特性,不需要在基类定义该虚函数,直接保留现有派生类的非虚sum实现即可,不需要做额外修改。
内容的提问来源于stack exchange,提问作者Antonio Molinaro
相关产品推荐
相关产品推荐

