1

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

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

在 C++中实现泛型的一种常见做法clone是基于 CRTP,例如,请参阅此 SO 帖子

鉴于我们需要clonevirtual或至少,表现为虚拟),以允许:

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

并且鉴于提议是不应声明具有显式 this 参数的成员函数virtual

是否还有一种方法可以使用 P0847 来实现具有动态行为且没有 CRTP的通用克隆

4

2 回答 2

3

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

于 2020-10-29T20:47:34.073 回答
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 显式传递给构造函数的能力,并且显式 this 参数是最派生的类型。

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

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

于 2020-10-30T18:39:24.933 回答