P0847推断出这一点——它是否可以在不需要CRTP的情况下允许通用克隆



P0847提出了对成员函数使用显式this参数的可能性。

在这个提议带来的其他好处中,CRTP在没有C、R甚至T的情况下也有很大的新可能性。

在C++中实现通用clone的一种常见做法是基于CRTP的,例如请参阅本SO文章。

假设我们需要clonevirtual(或者至少表现为虚拟的(,以允许:

Shape* pCopy = pShape->clone(); // get a copy of the correct runtime type

并且假设提议是具有显式此参数的成员函数不应声明为virtual

是否还有办法使用P0847来实现具有动态行为的通用克隆和不具有CRTP的

模板推导只使用静态类型,而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(

尚不清楚此建议是否允许在构造函数上显式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(一个条目(。

如果不能做到这一点,你可能不得不等待反思。

相关内容

最新更新