C++ 如何用继承实现方法链接?

C++ 如何用继承实现方法链接?,c++,crtp,method-chaining,C++,Crtp,Method Chaining,我的问题是,当我已经使用了Base类方法时,我无法从派生的类链接方法。我试图混合和的最顶层答案,但问题是其中一个总是返回同一个对象,另一个是返回void。我希望Base类能够被任何其他类继承 [解决此问题的最简单方法是将a()设为虚拟,并在类派生中重写它。但是如果Base被100个其他类继承,并且有100个其他方法要重写怎么办?这不是很好的扩展。] [另一个简单的解决方案是首先从派生的类调用方法,然后从基调用方法,但是…不] 所以,有可能在本地C++中编译下面的代码片段吗?(我对boost解决方

我的问题是,当我已经使用了
Base
类方法时,我无法从
派生的
类链接方法。我试图混合和的最顶层答案,但问题是其中一个总是返回同一个对象,另一个是返回
void
。我希望
Base
类能够被任何其他类继承

[解决此问题的最简单方法是将
a()
设为虚拟,并在类
派生
中重写它。但是如果
Base
被100个其他类继承,并且有100个其他方法要重写怎么办?这不是很好的扩展。] [另一个简单的解决方案是首先从
派生的
类调用方法,然后从
基调用方法,但是…不]

<>所以,有可能在本地C++中编译下面的代码片段吗?(我对boost解决方案不感兴趣)。如果
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);
    }
}
#包括
#包括
模板
阶级基础
{
公众:
T&a();
};
派生类:公共基
{
公众:

派生的&b(){std::cout不确定它是否是您想要的,但是使用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);
        }
    }
};
模板
阶级基础
{
公众:
auto&a()
{

std::cout不确定它是否是您想要的,但是使用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);
        }
    }
};
模板
阶级基础
{
公众:
auto&a()
{

std::cout
typename T=void
将对
T&
产生问题……我不确定我是否理解这个问题,但是,这是你想要的吗?是的@tedlynmo这正是我想要的。@tedlynmo我无法接受你的意见解决方案。这没关系。我自己对Jarod42的答案投了赞成票。
typename T=void
问题在于
T&
…我不确定我是否理解这个问题,但是,你想要什么?是的@TedLyngmo这正是我想要的。@TedLyngmo我不能接受你从评论中得出的解决方案。没关系。我自己对Jarod42的答案投了赞成票。你说“以前,你可以使用专业化”是什么意思?专门化整个类:
模板类基类{T&a(){return static_cast(*this);}};模板类基类{Base&a(){return*this;}
或专门化方法(返回类型应为
std::conditional_T
)谢谢,这非常有用。您所说的“以前,您可以使用专门化”是什么意思?专门化整个类:
模板类基类{T&a(){return static_cast(*this);}};模板类基类{Base&a(){return*this;}}
或专门化方法(返回类型应为
std::conditional_T
),谢谢,这非常有用。