提问人:einpoklum 提问时间:10/6/2022 最后编辑:Jan Schultkeeinpoklum 更新时间:9/24/2023 访问量:161
实现返回 *this(协变返回类型)的“虚拟”方法
Implementing a "virtual" method returning *this (covariant return type)
问:
我正在编写 C++ 类的层次结构,比方说 , 继承 , 继承 和 继承 。A
B
A
C
A
D
B
现在,所有这些类都必须有一个方法,其主体是:bar() &
{
A::foo();
return *this;
}
这是完全相同的代码,执行完全相同的操作 - 除了返回值的类型 - 它返回对类类型的左值引用。
现在,此方法的签名对于每个类都是不同的。但是 - 这本质上是相同的方法。问题是,按照目前的情况,我需要多次复制它的代码。如何避免这种代码重复?
我本来想用 CRTP 写一些 mixin,但当我进入细节时,它变得超级丑陋。
注意:在本例中,仅针对左值定义,以免涉及从右值返回的合法性问题。bar()
*this
答:
2赞
Jarod42
10/6/2022
#1
正如 Raymond Chen 所评论的那样,c++23 可以推断出这一点,从而允许如下代码:
struct A
{
template <typename Self>
Self& bar(this Self& self) // Here self is the static type which calls bar
// so potentially the derived type
{
self.A::foo(); // or self.foo();
return self;
}
// ...
};
struct B : A{};
struct C : A{};
struct D : B{};
但目前,CRTP 可能会有所帮助,例如:
struct A
{
// ...
};
template <typename Derived, typename Base>
struct A_CRTP : Base
{
Derived& bar()
{
A::foo();
return static_cast<Derived&>(*this);
}
// ...
};
struct B : A_CRTP<B, A> {};
struct C : A_CRTP<C, A> {};
struct D : A_CRTP<D, B> {};
评论
bar()
A
A&
static_cast
dynamic_cast
template<typename Final> struct A { Final& bar() { A::foo(); return static_cast<Final&>(*this); }}; template<typename Final> struct B : A<Final> {}; struct D: B<D>{};
struct A { template<typename Self> Self& bar(this Self& self) { self.foo(); return self;} }; struct B : A{}; struct D : B{};