简体   繁体   English

实现返回 *this(协变返回类型)的“虚拟”方法

[英]Implementing a "virtual" method returning *this (covariant return type)

I'm writing a hierarchy of classes of C++, let's say A , B inheriting A , C inheriting A , and D inheriting B .我正在编写 C++ 类的层次结构,假设AB继承AC继承AD继承B

Now, all of these classes must have a method bar() & , whose body is:现在,所有这些类都必须有一个方法bar() & ,其主体是:

{
    A::foo();
    return *this;
}

It's the exact same code, doing the exact same thing - except for the type of the return value - which returns an lvalue reference to the class' type.这是完全相同的代码,做完全相同的事情——除了返回值的类型——它返回一个对类类型的左值引用。

Now, the signature of this method would be different for every class. But - it's essentially the same method.现在,此方法的签名对于每个 class 都是不同的。但是 - 它本质上是相同的方法。 The thing is, the way things stand, I need to replicate the code for it many times.事情是这样的,我需要多次复制代码。 How can I avoid this code duplication?我怎样才能避免这种代码重复?

I was thinking of writing some mixin with CRTP, but when I get into the details it becomes super-ugly.我正在考虑用 CRTP 编写一些 mixin,但是当我深入细节时,它变得非常丑陋。

Note: For the purposes of this example, bar() is only defined for lvalues so as not to get into the question of legitimacy of returning *this from an rvalue.注意:出于本示例的目的, bar()仅为左值定义,以免涉及从右值返回*this的合法性问题。

As Raymond Chen commented, c++23 would have deducing this which allows code like:正如 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{};

But currently, CRTP might help, something like:但目前,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> {};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM