【问题标题】:How to implement method chaining with inheritance?如何使用继承实现方法链接?
【发布时间】:2021-05-27 20:52:21
【问题描述】:

我的问题是,当我已经使用 Base 类方法时,我无法从 Derived 类链接方法。我试图混合来自Returning a reference to the derived class from a base class methodCRTP and multilevel inheritance 的最高答案,但问题是其中一个总是返回相同的对象,另一个返回void。我希望Base 类能够被任何其他类继承。

[解决这个问题的简单方法是将a() 设为虚拟并在Derived 类中覆盖它。但是,如果Base 被 100 个其他类继承并有 100 个其他方法可以覆盖怎么办?这不是很好的缩放。] [另一个幼稚的解决方案是先从Derived类调用方法,然后从Base调用方法,但是......只是没有]

那么,是否有可能以某种方式在本机 C++ 中编译以下 sn-p? (我对提升解决方案不感兴趣)。如果main() 的代码不会改变,那就太理想了。

#include <iostream>
#include <type_traits>

template <typename T = void>
class Base
{
public:
    T& a();
 };

class Derived : public Base<Derived>
{
public:
    Derived& b() {std::cout << "b\n"; return *this;}
};


int main()
{
    Base base;
    base
        .a()
    ;
    
    Derived derived;
    derived
        .a()
        .b()
    ;
    
    return 0;
}

template <typename T>
T& Base<T>::a()
{
    std::cout << "a\n";
    if(std::is_same<T, void>::value)
    {
        return *this;
    }
    else
    {
        return static_cast<T&>(*this);
    }
}

如果我能写template &lt;typename T = Base&gt; class Base { ... :)

【问题讨论】:

  • typename T = voidT&amp; 有问题...
  • 我不确定我是否理解问题的含义,但是this 是您想要的吗?
  • 是的@TedLyngmo,这正是我想要的。
  • @TedLyngmo 我无法接受 cmets 的解决方案。
  • 没关系。我自己赞成 Jarod42 的回答。

标签: c++ crtp method-chaining


【解决方案1】:

不确定它是否是您想要的,但使用 C++17 和 if constexpr,您可能会这样做:

template <typename T = void>
class Base
{
public:
    auto& a()
    {
        std::cout << "a\n";
        if constexpr (std::is_same_v<T, void>) {
            return *this;   
        } else {
            return static_cast<T&>(*this);
        }
    }
};

Demo

以前,您可能会使用专业化。

【讨论】:

  • “以前,您可能会使用专业化”是什么意思?
  • 特化整个类:template &lt;typename T&gt; class Base { T&amp; a() { return static_cast&lt;T&amp;&gt;(*this); } }; template&lt;&gt; class Base&lt;void&gt; { Base&amp; a() { return *this; } } 或特化方法(返回类型应为 std::conditional_t&lt;std::is_same_v&lt;T, void&gt;, Base, T&gt;
  • 谢谢,这很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 2011-11-21
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
相关资源
最近更新 更多