gpt4 book ai didi

c++ - 在模板派生类中使用协变返回类型覆盖虚拟函数

转载 作者:行者123 更新时间:2023-12-01 14:42:27 25 4
gpt4 key购买 nike

我想重写模板派生类中的虚函数。但是,我想使用派生类作为返回类型。这是相应的代码:

class Abstract {
public:
virtual Abstract* allocate() const = 0;
};
template <typename Derived>
class Base : public Abstract {
public:
Derived* allocate() const override {
return new Derived;
}
};
class Concrete : public Base<Concrete> {
public:
};
int main() {
Concrete c;
delete c.allocate();
}
不幸的是,我的编译器无法识别 Derived实际上是从 Abstract派生的,并且失败并显示以下错误消息。
mwe.cpp: In instantiation of ‘class Base<Concrete>’:
mwe.cpp:12:25: required from here
mwe.cpp:8:14: error: invalid covariant return type for ‘Derived* Base<Derived>::allocate() const [with Derived = Concrete]’
Derived* allocate() const override {
^~~~~~~~
mwe.cpp:3:23: note: overridden function is ‘virtual Abstract* Abstract::allocate() const’
virtual Abstract* allocate() const = 0;
^~~~~~~~
allocate函数移到 Concrete类中可以解决此问题,但是在创建多个具体类时会导致代码重复。有没有办法使编译器知道 Derived实际上是从 Abstract派生的?

最佳答案

您可以模拟协变返回类型:
这里的重点是Reintroduce类。没有它,allocate将覆盖虚函数。有了它,它隐藏了继承的函数。

#include <iostream>

class Abstract {
public:
virtual Abstract* allocate() const = 0;
};

namespace details{
class Reintroduce {};

template <typename Derived>
class AllocImpl : public Abstract
{
public:
Abstract* allocate() const override {
return new Derived;
}
};
}


template <typename Derived>
class Base : public details::AllocImpl<Derived>
{
public:
Derived* allocate(details::Reintroduce = {}) const
{
return static_cast<Derived*>(details::AllocImpl<Derived>::allocate());
}
};

class Concrete : public Base<Concrete> {
public:
};


int main() {
Concrete c;
delete c.allocate();
}
如果我们可以不用 AllocImpl来实现它,那就太好了,但这会使调用变得模棱两可。

关于c++ - 在模板派生类中使用协变返回类型覆盖虚拟函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62919503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com