P0847 推论 - 它可以允许通用克隆而不需要 CRTP 吗?

问题描述 投票:0回答:2

P0847 提出了对成员函数使用显式

this
参数的可能性。

除了该提案带来的其他好处之外,还有无需 C、R 甚至 T 的 CRTP 的巨大新可能性。

在 C++ 中实现泛型

clone

 的常见做法是基于 CRTP,例如参见 
this SO post

鉴于我们需要

clone

 成为 
virtual
(或者至少表现得像虚拟),允许:

Shape* pCopy = pShape->clone(); // get a copy of the correct runtime type
并且鉴于建议是具有显式 this 参数的成员函数 

不得声明 virtual

是否仍然有办法使用 P0847 来实现具有动态行为且

没有 CRTP通用克隆

c++ crtp type-deduction c++23 explicit-object-parameter
2个回答
5
投票
模板推导只使用静态类型,而

Clone

需要动态类型,所以
virtual

P0847 主要允许变形

template <typename T> T* Foo(const T& obj); // With Obj base of T
进入

template <typename Self> Self* Obj::Foo(this const Self& obj);
您可以做的是使用智能指针简化协方差。

struct Clonable { virtual ~Clonable() = default; virtual Clonable* do_clone() const = 0; template <typename Self> std::unique_ptr<Self> clone(this const Self& self) { std::unique_ptr<Self>(self.do_clone()); } }; struct MyClass : Clonable { MyClass* do_clone() const override { return new MyClass(*this); } };
但是 CRTP 似乎更好,因为它可以避免为每种类型重写 

do_clone

(未来的反思可能会简化

Clonable


0
投票
尚不清楚该提案是否允许在构造函数上显式使用

this

如果确实如此,我们可以解决这个问题。

struct clonable { icloneable const*(*do_clone)(icloneable const*) = 0; template<class Derived> clonable( this Derived& ): do_clone([](icloneable const* vself)->icloneable const*{ return new Derived(*static_cast<Derived const*>(vself); }) {} icloneable const* clone() const { return do_clone( this ); } };
这依赖于将显式 this 传递给构造函数的能力,并且显式 this 参数是最派生的类型。

我们基本上自己实现了一个(一个条目的)vtable。

如果没有能力做到这一点,你可能需要等待反思。

© www.soinside.com 2019 - 2024. All rights reserved.