提问人:JensB 提问时间:10/5/2023 最后编辑:JensB 更新时间:10/5/2023 访问量:72
在这种情况下,对于具有类型约束的虚拟函数模板,是否有任何解决方法?
Is there any workaround for a virtual function template with a type constraint in this case?
问:
如果你有一个概念和一个类成员函数模板,如下所示:
template<typename T>
concept Vector2 = requires (T t) { t.x; t.y; };
struct Shape
{
bool contains(const Vector2 auto&) { ... }
};
有没有办法,通过一些解决方法,成为一个纯粹的虚拟功能?因此,子类(例如,、、等)可以像这样继承:contains
Circle
Polygon
struct Circle : public Shape
{
bool contains(const Vector2 auto&) const override;
};
显然,上述方法不起作用,因为不允许使用虚拟功能模板。
这个概念的原因是我使用来自不同库的 2D 功能,并且我希望它们各自的类能够传递给我的函数。这种设计模式本身是否是一个好主意,这不是我的问题,而只是我想要实现的东西是否可能。Vector2
Vector2
我四处搜索了一下,找到了一个建议基本访客模式的 SO 答案,但我很难看出我如何在这里应用它。
有没有办法实现接近我想要的东西,或者只是不可能?
(这是我之前一个问题的修改和更具体的版本。我被告知需要更多的信息和一个实际的例子来给出答案。
答:
0赞
Jarod42
10/5/2023
#1
您可以键入 erase 模板函数的参数。
由于您希望使用库中的对象来调用它,因此无法更改层次结构,因此可以使用 Sean Parent 模式,如下所示:
template <typename T>
class Vector2View
{
private:
struct IVector2 // internal erased type
{
virtual ~IVector2() = default;
virtual T getX() const = 0;
virtual void setX(T value) = 0;
virtual T getY() const = 0;
virtual void setY(T value) = 0;
};
template<typename U>
struct Vector2T : IVector2 // Wrapper around given type
{
explicit Vector2T(U& u) : u(u) {}
T getX() const override { return u.x; }
void setX(T value) override { u.x = value; }
T getY() const override { return u.y; }
void setY(T value) override { u.y = value; }
U& u;
};
public:
template <typename U>
requires (Vector2<U>)
/* implicit */ Vector2View(U& v) : ptr(std::make_unique<Vector2T<U>>(v)) {}
T getX() const { return ptr->getX(); }
void setX(T value) { return ptr->setX(value); }
T getY() const { return ptr->getY(); }
void setY(T value) { return ptr->setY(value); }
private:
std::unique_ptr<IVector2> ptr;
};
然后
struct Shape
{
virtual ~Shape() = default;
virtual bool contains(const Vector2View<double>&) const = 0;
};
评论
0赞
JensB
10/9/2023
此处使用堆内存是否会对性能关键型应用程序(如游戏)不利?即,每次调用函数 using 时分配并销毁一个实例(即 -reference)。Vector2T
U
Vector2View
0赞
Jarod42
10/10/2023
您可以调整代码以使用自定义分配器(可能使用自定义池),或者在类中放置缓冲区以避免头分配,或者使用指针函数和数据(因此主要内联 vtable)交换虚拟类。
评论