P0847 推导这个 - 它可以允许通用克隆而不需要 CRTP 吗?
P0847 deducing this - can it allow a generic clone without a need for CRTP?
P0847 提出了为成员函数使用显式 this
参数的可能性。
在这个提议带来的其他好东西中,还有 CRTP without C, R and even T 的巨大新可能性。
在 C++ 中实现泛型 clone
的常见做法是基于 CRTP,例如参见 [=18=]。
鉴于我们需要 clone
成为 virtual
(或者至少,表现为虚拟),以允许:
Shape* pCopy = pShape->clone(); // get a copy of the correct runtime type
并且鉴于提案是具有显式 this 参数的成员函数 不应声明 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 显式传递给构造函数的能力,并且显式 this 参数是 most-derived 类型。
我们基本上自己实现了一个 vtable(一个条目)。
如果无法执行此操作,您可能需要等待反射。
P0847 提出了为成员函数使用显式 this
参数的可能性。
在这个提议带来的其他好东西中,还有 CRTP without C, R and even T 的巨大新可能性。
在 C++ 中实现泛型 clone
的常见做法是基于 CRTP,例如参见 [=18=]。
鉴于我们需要 clone
成为 virtual
(或者至少,表现为虚拟),以允许:
Shape* pCopy = pShape->clone(); // get a copy of the correct runtime type
并且鉴于提案是具有显式 this 参数的成员函数 不应声明 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 显式传递给构造函数的能力,并且显式 this 参数是 most-derived 类型。
我们基本上自己实现了一个 vtable(一个条目)。
如果无法执行此操作,您可能需要等待反射。